一、概述
1 什么是多租戶架構?
多租戶架構是指在一個應用中支持多個租戶(Tenant)同時訪問,每個租戶擁有獨立的資源和數據,并且彼此之間完全隔離。通俗來說,多租戶就是把一個應用按照客戶的需求“分割”成多個獨立的實例,每個實例互不干擾。
2 多租戶架構的優勢
更好地滿足不同租戶的個性化需求。
節約開發成本,通過復用代碼,快速上線新的租戶實例。
增強了系統的可擴展性和可伸縮性,支持水平擴展,每個租戶的數據和資源均可管理和控制。
3 實現多租戶架構的技術選擇
對于實現多租戶架構技術不是最重要的最重要的是正確的架構思路。但是選擇正確的技術可以更快地實現多租戶架構。
二、設計思路
1 架構選型
基于Java開發多租戶應用推薦使用Spring Boot和Spring Cloud。Spring Boot能快速搭建應用并提供許多成熟的插件。Spring Cloud則提供了許多實現微服務架構的工具和組件。
1.1 Spring Boot
使用Spring Boot可以簡化項目的搭建過程自動配置許多常見的第三方庫和組件,減少了開發人員的工作量。
@RestController publicclassTenantController{ @GetMapping("/hello") publicStringhello(@RequestHeader("tenant-id")StringtenantId){ return"Hello,"+tenantId; } }
1.2 Spring Cloud
在架構多租戶的系統時Spring Cloud會更加有用。Spring Cloud提供了一些成熟的解決方案,如Eureka、Zookeeper、Consul等,以實現服務發現、負載均衡等微服務功能。
2 數據庫設計
在多租戶環境中數據庫必須為每個租戶分別存儲數據并確保數據隔離。我們通常使用以下兩種方式實現:
多個租戶共享相同的數據庫,每個表中都包含tenant_id這一列,用于區分不同租戶的數據。
為每個租戶創建單獨的數據庫,每個數據庫內的表結構相同,但數據相互隔離。
3 應用多租戶部署
為了實現多租戶在應用部署時我們需要考慮以下兩個問題。
3.1 應用隔離
在多租戶環境中不同租戶需要訪問不同的資源,因此需要進行應用隔離。可以通過構建獨立的容器或虛擬機、使用命名空間等方式實現。Docker就是一種非常流行的隔離容器技術。
3.2 應用配置
由于每個租戶都有自己的配置需求因此需要為每個租戶分別設置應用配置信息,例如端口號、SSL證書等等。這些配置可以存儲在數據庫中,也可以存儲在云配置中心中。
4 租戶管理
在多租戶系統中需要能夠管理不同租戶的數據和資源,同時需要為每個租戶分配相應的權限。解決方案通常包括以下兩部分。
4.1 租戶信息維護
租戶信息的維護包括添加、修改、刪除、查詢等操作,要求能夠根據租戶名稱或租戶ID快速查找對應的租戶信息。
CREATETABLEtenant( idBIGINTAUTO_INCREMENTPRIMARYKEY, nameVARCHAR(50)NOTNULLUNIQUE, descriptionVARCHAR(255), created_timeTIMESTAMPDEFAULTCURRENT_TIMESTAMP, updated_timeTIMESTAMPDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP );
4.2 租戶權限控制
在多租戶應用中必須為每個租戶分別設置對系統資源的訪問權限。例如,A租戶和B租戶不能訪問彼此的數據。
@EnableGlobalMethodSecurity(prePostEnabled=true) @Configuration publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{ @Override protectedvoidconfigure(HttpSecurityhttp)throwsException{ http.authorizeRequests() .antMatchers("/api/tenant/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin(); } @Autowired publicvoidconfigureGlobal(AuthenticationManagerBuilderauth)throwsException{ auth.userDetailsService(userDetailsService()) .passwordEncoder(newBCryptPasswordEncoder()) .and() .inMemoryAuthentication() .withUser("admin") .password(newBCryptPasswordEncoder().encode("123456")) .roles("ADMIN"); } }
三、技術實現
1 Spring Boot中的多租戶實現
在Spring Boot中可以通過多數據源和動態路由來實現多租戶機制。
1.1 多數據源實現
多數據源是指為不同的租戶配置不同的數據源,使得每個租戶都可以訪問自己的獨立數據。具體實現方法如下:
@Configuration publicclassDataSourceConfig{ @Bean(name="dataSourceA") @ConfigurationProperties(prefix="spring.datasource.a") publicDataSourcedataSourceA(){ returnDataSourceBuilder.create().build(); } @Bean(name="dataSourceB") @ConfigurationProperties(prefix="spring.datasource.b") publicDataSourcedataSourceB(){ returnDataSourceBuilder.create().build(); } @Bean(name="dataSourceC") @ConfigurationProperties(prefix="spring.datasource.c") publicDataSourcedataSourceC(){ returnDataSourceBuilder.create().build(); } }
以上代碼是配置了三個數據源分別對應三個租戶。然后在使用時,可以使用注解標記需要連接的數據源。
@Service publicclassProductService{ @Autowired @Qualifier("dataSourceA") privateDataSourcedataSource; //... }
1.2 動態路由實現
動態路由是指根據請求的URL或參數動態地切換到對應租戶的數據源。具體實現如下:
publicclassDynamicDataSourceextendsAbstractRoutingDataSource{ @Override protectedObjectdetermineCurrentLookupKey(){ returnTenantContextHolder.getTenantId(); } } @Configuration publicclassDataSourceConfig{ @Bean(name="dataSource") @ConfigurationProperties(prefix="spring.datasource") publicDataSourcedataSource(){ returnDataSourceBuilder.create().type(DynamicDataSource.class).build(); } }
以上是動態路由的核心代碼DynamicDataSource繼承自AbstractRoutingDataSource,通過determineCurrentLookupKey()方法動態獲得租戶ID,然后切換到對應的數據源。
2 Spring Cloud中的多租戶實現
在Spring Cloud中可以通過服務注冊與發現、配置中心、負載均衡等方式實現多租戶機制。
2.1 服務注冊與發現
使用Spring Cloud中的Eureka實現服務注冊與發現。每個租戶的服務都在注冊中心以不同的應用名稱進行注冊,客戶端可以通過服務名稱來訪問對應租戶的服務。
2.2 配置中心
使用Spring Cloud Config作為配置中心。配置文件以租戶ID進行區分,客戶端通過讀取對應租戶的配置文件來獲取配置信息。
2.3 負載均衡
使用Spring Cloud Ribbon作為負載均衡器。根據請求的URL或參數選擇對應租戶的服務實例進行請求轉發。
2.4 API
在API網關層面實現多租戶機制根據請求的URL或參數判斷所屬租戶,并轉發到對應租戶的服務實例。
四、 應用場景
1 私有云環境
私有云環境指的是由企業自行搭建的云環境,不對外提供服務,主要應用于企業內部的數據存儲、管理、共享和安全控制。相較于公有云,私有云的優點在于可以更好地保護企業核心數據,同時也能夠滿足企業對于數據安全性和可控性的要求。
2 公有云環境
公有云環境指的是由云服務商搭建并對外提供服務的云環境,用戶可以根據需要購買相應的云服務,如云存儲、云計算、云數據庫等。相較于私有云,公有云的優點在于具有成本低廉、彈性伸縮、全球化部署等特點,能夠更好地滿足企業快速發展的需求。
3 企業級應用
企業級應用是指面向企業客戶的應用程序,主要包括ERP、CRM、OA等一系列應用系統。這類應用的特點在于功能強大、流程復雜、數據量大,需要滿足企業的高效率、高可靠性、高安全性和易維護性等要求。在云計算環境下,企業可以將這些應用部署在私有云或公有云上,減少了硬件設備的投入和維護成本,提高了管理效率。
五、實現步驟
1 搭建Spring Boot和Spring Cloud環境
首先需要在Maven項目中引入以下依賴:
org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-dependencies 2020.0.3 pom import
然后需要在application.yml中配置相應的參數,如下所示:
spring: datasource: url:jdbc//localhost:3306/appdb?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username:root password:123456 mybatis: type-aliases-package:com.example.demo.model mapper-locations:classpath:mapper/*.xml server: port:8080 eureka: client: serviceUrl: defaultZone:http://localhost:8761/eureka/ management: endpoints: web: exposure: include:"*"
其中datasource.url為數據庫連接的URL,username和password為數據庫連接的賬號和密碼;server.port為Spring Boot應用啟動的端口;eureka.client.serviceUrl.defaultZone為Eureka服務注冊中心的URL。
2 修改數據庫設計
接下來需要對數據庫進行相應的修改,以支持多租戶部署。具體來說,我們需要在數據庫中添加一個與租戶相關的字段,以便在應用中區分不同的租戶。
3 實現應用多租戶部署
接著需要在代碼中實現應用的多租戶部署功能。具體來說,我們需要為每個租戶實例化對應的Spring Bean,并根據租戶ID將請求路由到相應的Bean中去處理。
以下是一個簡單的實現示例:
@Configuration publicclassMultiTenantConfig{ //提供對應租戶的數據源 @Bean publicDataSourcedataSource(TenantRegistrytenantRegistry){ returnnewTenantAwareDataSource(tenantRegistry); } //多租戶Session工廠 @Bean(name="sqlSessionFactory") publicSqlSessionFactorysqlSessionFactory(DataSourcedataSource) throwsException{ SqlSessionFactoryBeansessionFactory=newSqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); returnsessionFactory.getObject(); } //動態切換租戶 @Bean publicMultiTenantInterceptormultiTenantInterceptor(TenantResolvertenantResolver){ MultiTenantInterceptorinterceptor=newMultiTenantInterceptor(); interceptor.setTenantResolver(tenantResolver); returninterceptor; } //注冊攔截器 @Override publicvoidaddInterceptors(InterceptorRegistryregistry){ registry.addInterceptor(multiTenantInterceptor()); } //注冊租戶信息 @Bean publicTenantRegistrytenantRegistry(){ returnnewTenantRegistryImpl(); } //解析租戶ID @Bean publicTenantResolvertenantResolver(){ returnnewHeaderTenantResolver(); } }
其中MultiTenantConfig是多租戶部署的核心配置類,它提供了對應租戶數據源、多租戶Session工廠、動態切換租戶等功能。
4 實現租戶管理
最后需要實現一個租戶管理的功能,以便在系統中管理不同的租戶。具體來說,我們可以使用Spring Cloud的服務注冊與發現組件Eureka來注冊每個租戶的實例,并在管理界面中進行相應的操作。另外,我們還需要為每個租戶提供一個獨立的數據庫,以保證數據隔離性。
六、小結回顧
本文詳細介紹了如何使用Spring Boot和Spring Cloud實現一個支持多租戶部署的應用。主要包括搭建Spring Boot和Spring Cloud環境、修改數據庫設計、實現應用多租戶部署、實現租戶管理等方面。
應用場景主要包括SaaS應用、多租戶云服務等。優劣勢主要體現在提升了應用的可擴展性和可維護性,但也增加了部署和管理的復雜度。未來的改進方向可以考慮進一步提升多租戶管理的自動化程度,減少人工干預和錯誤率。
審核編輯:劉清
-
JAVA
+關注
關注
19文章
2958瀏覽量
104552 -
CRM
+關注
關注
1文章
145瀏覽量
21111 -
URL
+關注
關注
0文章
139瀏覽量
15312 -
SSL
+關注
關注
0文章
125瀏覽量
25721 -
虛擬機
+關注
關注
1文章
908瀏覽量
28094 -
SpringBoot
+關注
關注
0文章
173瀏覽量
169
原文標題:基于 SpringBoot 實現多租戶架構:支持應用多租戶部署和管理
文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論