Multi-tenancy in Java

9,478 views

Published on

An introduction to multi-tenancy in Java enterprise applications. It covers the steps needed to use Hibernate's support, integration with migration framework Liquibase and logging.

Published in: Technology

Multi-tenancy in Java

  1. 1. MULTI-TENANCY in Java applications @ladislavGazo gazo@seges.sk
  2. 2. THE APPLICATION user | bunch of JavaScript | service | domain model
  3. 3. IMPLICATION user1 ... userN | same bunch of JavaScript | service | ONE database
  4. 4. ONE APPLICATION TO RULE THEM ALL The term multi-tenancy in general is applied to software development to indicate an architecture in which a single running instance of an application simultaneously serves multiple clients (tenants). This is highly common in SaaS solutions. Isolating information (data, customizations, etc) pertaining to the various tenants is a particular challenge in these systems.
  5. 5. SPLIT ME NOW! user1 -> BA, user2 -> BA, user 3 -> KE, user 4 -> ZA | again the same JavaScript | (almost) the same service | DB (BA), DB (KE), DB (ZA)
  6. 6. a lot of "tenant" dependent data - high volumes performance separation -> easier backup and restore scalability of front-end and service layer
  7. 7. HIBERNATE IS THE EASIEST
  8. 8. MULTI-TENANT CONFIGURATION <rprynm=hbraemlieac"vle"AAAE / poet ae"ient.utTnny au=DTBS" > <rprynm=hbraetnn_dniirrsle"vle"ksgshodlnecniuainMlieatdniireovr / poet ae"ient.eatietfe_eovr au=s.ee.rdeei.ofgrto.utTnnIetfeRsle" > <rprynm=hbraemlitnn_oncinpoie"vle"r.ient.evc.dccnetossi poet ae"ient.ut_eatcneto_rvdr au=oghbraesriejb.oncin.p. DtSucBsdutTnnCnetoPoieIp"/ aaoreaeMlieatoncinrvdrml > <rprynm=hbraecneto.aaore vle"aacm/n/dch"/ poet ae"ient.oncindtsuc" au=jv:opevjb/r > <rprynm=hbraemlitnn.aaoreietfe_o_n"vle"eal"/ poet ae"ient.ut_eatdtsuc.dniirfray au=dfut >
  9. 9. SWITCH IT ON hbraemlieac ient.utTnny
  10. 10. CONFIGURE WHERE TO LOOK FOR THE CURRENT TENANT IDENTIFIER hbraetnn_dniirrsle ient.eatietfe_eovr
  11. 11. WHERE ARE MY CONNECTIONS? hbraemlitnn_oncinpoie ient.ut_eatcneto_rvdr Hibernate's DataSourceBasedMultiTenantConnectionProviderImpl utilizes JNDI lookups
  12. 12. POINT TO JNDI ROOT FOR DATASOURCES hbraecneto.aaore ient.oncindtsuc
  13. 13. ... AND THE DEFAULT hbraemlitnn.aaoreietfe_o_n ient.ut_eatdtsuc.dniirfray So in the end = jv:opevjb/rdfut aacm/n/dch/eal
  14. 14. BUT THERE ARE THINGS THAT DON'T WORK EHCache configuration from previous version is different Hibernate's internal schema update does not work NPE !!! ........ who would have said that
  15. 15. MIGRATION
  16. 16. HIBERNATE EXPORTER is not helpful
  17. 17. DO YOU HAVE ENVERS? then you need custom exporter
  18. 18. IT IS EASY TO WRITE but don't forget the AuditConfiguration EbCniuainjaofgrto =nwEbCniuain)cniue j3ofgrto pCniuain e j3ofgrto(.ofgr( uiNm,nl) ntae ul; Cniuainhbraeofgrto =jaofgrto ofgrto ientCniuain pCniuain .eHbraeofgrto(; gtientCniuain) hbraeofgrto.ulMpig(; ientCniuainbidapns) Adtofgrto adtofgrto =Adtofgrto.eFr uiCniuain uiCniuain uiCniuaingto( hbraeofgrto) ientCniuain; and use EnversSchemaGenerator at last
  19. 19. GET RID OF NPE BUG {"ient.utTnny, hbraemlieac" "ient.eatietfe_eovr, hbraetnn_dniirrsle" "ient.ut_eatcneto_rvdr, hbraemlitnn_oncinpoie" "ient.oncindtsuc" hbraecneto.aaore, "ient.ut_eatdtsuc.dniirfray } hbraemlitnn.aaoreietfe_o_n"
  20. 20. RUN THE EXPORTER FROM MAVEN
  21. 21. COMBINE IT WITH LIQUIBASE version 3.0.6 contains feature to populate all tenant databases Mlieatpigiubs utTnnSrnLqiae
  22. 22. DON'T FORGET... it is maintenable but generated SQL needs to be checked existing databases must be moved to "point 0"
  23. 23. A BIT OF LOGGING http://www.slf4j.org/faq.html#logging_performance Importance of logging - using MDC to track requests MCpt"eat,cinOg) D.u(tnn" letrz; lgjapne.totlyu.ovrinatr =AP[dIO61]-%5 o4.pedrsdu.aotCnesoPten P %{S80} -p [t%{eat|Xrqetd]%:M%3.0{}-%% %|Xtnn}%{eusI} F% -03c1 mn
  24. 24. AND THE MOST BORING... DESIGN your app to be multi-tenant
  25. 25. SEND TENANT IDENTIFICATION in HTTP Header use Filter to get it out in Service parameters using ThreadLocal variable via tenant-URL-based service calls rmi://localhost:12345/<tenant>/<service> etc...
  26. 26. THANKS FOR LISTENING @ladislavGazo gazo@seges.sk

×