1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Spring Boot 優(yōu)雅實(shí)現(xiàn)多租戶架構(gòu)

        共 13707字,需瀏覽 28分鐘

         ·

        2024-04-19 12:25

        來源:blog.csdn.net/u010349629/article/details/130737253

        ?? 歡迎加入小哈的星球 ,你將獲得: 專屬的項(xiàng)目實(shí)戰(zhàn) / Java 學(xué)習(xí)路線 / 一對(duì)一提問 / 學(xué)習(xí)打卡 /  贈(zèng)書福利


        全棧前后端分離博客項(xiàng)目 2.0 版本完結(jié)啦, 演示鏈接http://116.62.199.48/ ,新項(xiàng)目正在醞釀中。全程手摸手,后端 + 前端全棧開發(fā),從 0 到 1 講解每個(gè)功能點(diǎn)開發(fā)步驟,1v1 答疑,直到項(xiàng)目上線。目前已更新了239小節(jié),累計(jì)38w+字,講解圖:1645張,還在持續(xù)爆肝中.. 后續(xù)還會(huì)上新更多項(xiàng)目,目標(biāo)是將Java領(lǐng)域典型的項(xiàng)目都整一波,如秒殺系統(tǒng), 在線商城, IM即時(shí)通訊,Spring Cloud Alibaba 等等,戳我加入學(xué)習(xí),已有1300+小伙伴加入(早鳥價(jià)超低)


        • 一、概述
        • 二、設(shè)計(jì)思路
        • 三、技術(shù)實(shí)現(xiàn)
        • 四、 應(yīng)用場景
        • 五、實(shí)現(xiàn)步驟
        • 六、小結(jié)回顧

        一、概述

        1 什么是多租戶架構(gòu)?

        多租戶架構(gòu)是指在一個(gè)應(yīng)用中支持多個(gè)租戶(Tenant)同時(shí)訪問,每個(gè)租戶擁有獨(dú)立的資源和數(shù)據(jù),并且彼此之間完全隔離。通俗來說,多租戶就是把一個(gè)應(yīng)用按照客戶的需求“分割”成多個(gè)獨(dú)立的實(shí)例,每個(gè)實(shí)例互不干擾。

        2 多租戶架構(gòu)的優(yōu)勢

        • 更好地滿足不同租戶的個(gè)性化需求。
        • 可以降低運(yùn)維成本,減少硬件、網(wǎng)絡(luò)等基礎(chǔ)設(shè)施的投入。
        • 節(jié)約開發(fā)成本,通過復(fù)用代碼,快速上線新的租戶實(shí)例。
        • 增強(qiáng)了系統(tǒng)的可擴(kuò)展性和可伸縮性,支持水平擴(kuò)展,每個(gè)租戶的數(shù)據(jù)和資源均可管理和控制。

        3 實(shí)現(xiàn)多租戶架構(gòu)的技術(shù)選擇

        對(duì)于實(shí)現(xiàn)多租戶架構(gòu)技術(shù)不是最重要的最重要的是正確的架構(gòu)思路。但是選擇正確的技術(shù)可以更快地實(shí)現(xiàn)多租戶架構(gòu)。

        二、設(shè)計(jì)思路

        1 架構(gòu)選型

        基于Java開發(fā)多租戶應(yīng)用推薦使用Spring Boot和Spring Cloud。Spring Boot能快速搭建應(yīng)用并提供許多成熟的插件。Spring Cloud則提供了許多實(shí)現(xiàn)微服務(wù)架構(gòu)的工具和組件。

        1.1 Spring Boot

        使用Spring Boot可以簡化項(xiàng)目的搭建過程自動(dòng)配置許多常見的第三方庫和組件,減少了開發(fā)人員的工作量。

        @RestController
        public class TenantController {

            @GetMapping("/hello")
            public String hello(@RequestHeader("tenant-id") String tenantId) {
                return "Hello, " + tenantId;
            }
        }
        1.2 Spring Cloud

        在架構(gòu)多租戶的系統(tǒng)時(shí)Spring Cloud會(huì)更加有用。Spring Cloud提供了一些成熟的解決方案,如Eureka、Zookeeper、Consul等,以實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)、負(fù)載均衡等微服務(wù)功能。

        2 數(shù)據(jù)庫設(shè)計(jì)

        在多租戶環(huán)境中數(shù)據(jù)庫必須為每個(gè)租戶分別存儲(chǔ)數(shù)據(jù)并確保數(shù)據(jù)隔離。我們通常使用以下兩種方式實(shí)現(xiàn):

        • 多個(gè)租戶共享相同的數(shù)據(jù)庫,每個(gè)表中都包含tenant_id這一列,用于區(qū)分不同租戶的數(shù)據(jù)。
        • 為每個(gè)租戶創(chuàng)建單獨(dú)的數(shù)據(jù)庫,每個(gè)數(shù)據(jù)庫內(nèi)的表結(jié)構(gòu)相同,但數(shù)據(jù)相互隔離。

        3 應(yīng)用多租戶部署

        為了實(shí)現(xiàn)多租戶在應(yīng)用部署時(shí)我們需要考慮以下兩個(gè)問題。

        3.1 應(yīng)用隔離

        在多租戶環(huán)境中不同租戶需要訪問不同的資源,因此需要進(jìn)行應(yīng)用隔離??梢酝ㄟ^構(gòu)建獨(dú)立的容器或虛擬機(jī)、使用命名空間等方式實(shí)現(xiàn)。Docker就是一種非常流行的隔離容器技術(shù)。

        3.2 應(yīng)用配置

        由于每個(gè)租戶都有自己的配置需求因此需要為每個(gè)租戶分別設(shè)置應(yīng)用配置信息,例如端口號(hào)、SSL證書等等。這些配置可以存儲(chǔ)在數(shù)據(jù)庫中,也可以存儲(chǔ)在云配置中心中。

        4 租戶管理

        在多租戶系統(tǒng)中需要能夠管理不同租戶的數(shù)據(jù)和資源,同時(shí)需要為每個(gè)租戶分配相應(yīng)的權(quán)限。解決方案通常包括以下兩部分。

        4.1 租戶信息維護(hù)

        租戶信息的維護(hù)包括添加、修改、刪除、查詢等操作,要求能夠根據(jù)租戶名稱或租戶ID快速查找對(duì)應(yīng)的租戶信息。

        CREATE TABLE tenant (
            id BIGINT AUTO_INCREMENT PRIMARY KEY,
            name VARCHAR(50) NOT NULL UNIQUE,
            description VARCHAR(255),
            created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
        );
        4.2 租戶權(quán)限控制

        在多租戶應(yīng)用中必須為每個(gè)租戶分別設(shè)置對(duì)系統(tǒng)資源的訪問權(quán)限。例如,A租戶和B租戶不能訪問彼此的數(shù)據(jù)。

        @EnableGlobalMethodSecurity(prePostEnabled = true)
        @Configuration
        public class SecurityConfig extends WebSecurityConfigurerAdapter {

            @Override
            protected void configure(HttpSecurity http) throws Exception {
                http.authorizeRequests()
                        .antMatchers("/api/tenant/**").hasRole("ADMIN")
                        .anyRequest().authenticated()
                        .and()
                        .formLogin();
            }

            @Autowired
            public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
                auth.userDetailsService(userDetailsService())
                        .passwordEncoder(new BCryptPasswordEncoder())
                        .and()
                        .inMemoryAuthentication()
                        .withUser("admin")
                        .password(new BCryptPasswordEncoder().encode("123456"))
                        .roles("ADMIN");
            }
        }

        三、技術(shù)實(shí)現(xiàn)

        1 Spring Boot中的多租戶實(shí)現(xiàn)

        在Spring Boot中可以通過多數(shù)據(jù)源和動(dòng)態(tài)路由來實(shí)現(xiàn)多租戶機(jī)制。

        1.1 多數(shù)據(jù)源實(shí)現(xiàn)

        多數(shù)據(jù)源是指為不同的租戶配置不同的數(shù)據(jù)源,使得每個(gè)租戶都可以訪問自己的獨(dú)立數(shù)據(jù)。具體實(shí)現(xiàn)方法如下:

        @Configuration
        public class DataSourceConfig {
            @Bean(name = "dataSourceA")
            @ConfigurationProperties(prefix = "spring.datasource.a")
            public DataSource dataSourceA() {
                return DataSourceBuilder.create().build();
            }

            @Bean(name = "dataSourceB")
            @ConfigurationProperties(prefix = "spring.datasource.b")
            public DataSource dataSourceB() {
                return DataSourceBuilder.create().build();
            }

            @Bean(name = "dataSourceC")
            @ConfigurationProperties(prefix = "spring.datasource.c")
            public DataSource dataSourceC() {
                return DataSourceBuilder.create().build();
            }
        }

        以上代碼是配置了三個(gè)數(shù)據(jù)源分別對(duì)應(yīng)三個(gè)租戶。然后在使用時(shí),可以使用注解標(biāo)記需要連接的數(shù)據(jù)源。

        @Service
        public class ProductService {
            @Autowired
            @Qualifier("dataSourceA")
            private DataSource dataSource;

            // ...
        }
        1.2 動(dòng)態(tài)路由實(shí)現(xiàn)

        動(dòng)態(tài)路由是指根據(jù)請(qǐng)求的URL或參數(shù)動(dòng)態(tài)地切換到對(duì)應(yīng)租戶的數(shù)據(jù)源。具體實(shí)現(xiàn)如下:

        public class DynamicDataSource extends AbstractRoutingDataSource {
            @Override
            protected Object determineCurrentLookupKey() {
                return TenantContextHolder.getTenantId();
            }
        }

        @Configuration
        public class DataSourceConfig {
            @Bean(name = "dataSource")
            @ConfigurationProperties(prefix = "spring.datasource")
            public DataSource dataSource() {
                return DataSourceBuilder.create().type(DynamicDataSource.class).build();
            }
        }

        以上是動(dòng)態(tài)路由的核心代碼DynamicDataSource繼承自AbstractRoutingDataSource,通過determineCurrentLookupKey()方法動(dòng)態(tài)獲得租戶ID,然后切換到對(duì)應(yīng)的數(shù)據(jù)源。

        2 Spring Cloud中的多租戶實(shí)現(xiàn)

        在Spring Cloud中可以通過服務(wù)注冊(cè)與發(fā)現(xiàn)、配置中心、負(fù)載均衡等方式實(shí)現(xiàn)多租戶機(jī)制。

        2.1 服務(wù)注冊(cè)與發(fā)現(xiàn)

        使用Spring Cloud中的Eureka實(shí)現(xiàn)服務(wù)注冊(cè)與發(fā)現(xiàn)。每個(gè)租戶的服務(wù)都在注冊(cè)中心以不同的應(yīng)用名稱進(jìn)行注冊(cè),客戶端可以通過服務(wù)名稱來訪問對(duì)應(yīng)租戶的服務(wù)。

        2.2 配置中心

        使用Spring Cloud Config作為配置中心。配置文件以租戶ID進(jìn)行區(qū)分,客戶端通過讀取對(duì)應(yīng)租戶的配置文件來獲取配置信息。

        2.3 負(fù)載均衡

        使用Spring Cloud Ribbon作為負(fù)載均衡器。根據(jù)請(qǐng)求的URL或參數(shù)選擇對(duì)應(yīng)租戶的服務(wù)實(shí)例進(jìn)行請(qǐng)求轉(zhuǎn)發(fā)。

        2.4 API

        在API網(wǎng)關(guān)層面實(shí)現(xiàn)多租戶機(jī)制根據(jù)請(qǐng)求的URL或參數(shù)判斷所屬租戶,并轉(zhuǎn)發(fā)到對(duì)應(yīng)租戶的服務(wù)實(shí)例。

        四、 應(yīng)用場景

        1 私有云環(huán)境

        私有云環(huán)境指的是由企業(yè)自行搭建的云環(huán)境,不對(duì)外提供服務(wù),主要應(yīng)用于企業(yè)內(nèi)部的數(shù)據(jù)存儲(chǔ)、管理、共享和安全控制。相較于公有云,私有云的優(yōu)點(diǎn)在于可以更好地保護(hù)企業(yè)核心數(shù)據(jù),同時(shí)也能夠滿足企業(yè)對(duì)于數(shù)據(jù)安全性和可控性的要求。

        2 公有云環(huán)境

        公有云環(huán)境指的是由云服務(wù)商搭建并對(duì)外提供服務(wù)的云環(huán)境,用戶可以根據(jù)需要購買相應(yīng)的云服務(wù),如云存儲(chǔ)、云計(jì)算、云數(shù)據(jù)庫等。相較于私有云,公有云的優(yōu)點(diǎn)在于具有成本低廉、彈性伸縮、全球化部署等特點(diǎn),能夠更好地滿足企業(yè)快速發(fā)展的需求。

        3 企業(yè)級(jí)應(yīng)用

        企業(yè)級(jí)應(yīng)用是指面向企業(yè)客戶的應(yīng)用程序,主要包括ERP、CRM、OA等一系列應(yīng)用系統(tǒng)。這類應(yīng)用的特點(diǎn)在于功能強(qiáng)大、流程復(fù)雜、數(shù)據(jù)量大,需要滿足企業(yè)的高效率、高可靠性、高安全性和易維護(hù)性等要求。在云計(jì)算環(huán)境下,企業(yè)可以將這些應(yīng)用部署在私有云或公有云上,減少了硬件設(shè)備的投入和維護(hù)成本,提高了管理效率。

        五、實(shí)現(xiàn)步驟

        1 搭建Spring Boot和Spring Cloud環(huán)境

        首先需要在Maven項(xiàng)目中引入以下依賴:

        <!-- Spring Boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring Cloud -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2020.0.3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        然后需要在application.yml中配置相應(yīng)的參數(shù),如下所示:

        spring:
          datasource:
            url: jdbc:mysql://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為數(shù)據(jù)庫連接的URL,username和password為數(shù)據(jù)庫連接的賬號(hào)和密碼;server.port為Spring Boot應(yīng)用啟動(dòng)的端口;eureka.client.serviceUrl.defaultZone為Eureka服務(wù)注冊(cè)中心的URL。

        2 修改數(shù)據(jù)庫設(shè)計(jì)

        接下來需要對(duì)數(shù)據(jù)庫進(jìn)行相應(yīng)的修改,以支持多租戶部署。具體來說,我們需要在數(shù)據(jù)庫中添加一個(gè)與租戶相關(guān)的字段,以便在應(yīng)用中區(qū)分不同的租戶。

        3 實(shí)現(xiàn)應(yīng)用多租戶部署

        接著需要在代碼中實(shí)現(xiàn)應(yīng)用的多租戶部署功能。具體來說,我們需要為每個(gè)租戶實(shí)例化對(duì)應(yīng)的Spring Bean,并根據(jù)租戶ID將請(qǐng)求路由到相應(yīng)的Bean中去處理。

        以下是一個(gè)簡單的實(shí)現(xiàn)示例:

        @Configuration
        public class MultiTenantConfig {
         
            // 提供對(duì)應(yīng)租戶的數(shù)據(jù)源
            @Bean
            public DataSource dataSource(TenantRegistry tenantRegistry) {
                return new TenantAwareDataSource(tenantRegistry);
            }
         
            // 多租戶Session工廠
            @Bean(name = "sqlSessionFactory")
            public SqlSessionFactory sqlSessionFactory(DataSource dataSource)
                    throws Exception {
                SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
                sessionFactory.setDataSource(dataSource);
                return sessionFactory.getObject();
            }
         
            // 動(dòng)態(tài)切換租戶
            @Bean
            public MultiTenantInterceptor multiTenantInterceptor(TenantResolver tenantResolver) {
                MultiTenantInterceptor interceptor = new MultiTenantInterceptor();
                interceptor.setTenantResolver(tenantResolver);
                return interceptor;
            }
         
            // 注冊(cè)攔截器
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(multiTenantInterceptor());
            }
         
            // 注冊(cè)租戶信息
            @Bean
            public TenantRegistry tenantRegistry() {
                return new TenantRegistryImpl();
            }
             
            // 解析租戶ID
            @Bean
            public TenantResolver tenantResolver() {
                return new HeaderTenantResolver();
            }
         
        }

        其中MultiTenantConfig是多租戶部署的核心配置類,它提供了對(duì)應(yīng)租戶數(shù)據(jù)源、多租戶Session工廠、動(dòng)態(tài)切換租戶等功能。

        4 實(shí)現(xiàn)租戶管理

        最后需要實(shí)現(xiàn)一個(gè)租戶管理的功能,以便在系統(tǒng)中管理不同的租戶。具體來說,我們可以使用Spring Cloud的服務(wù)注冊(cè)與發(fā)現(xiàn)組件Eureka來注冊(cè)每個(gè)租戶的實(shí)例,并在管理界面中進(jìn)行相應(yīng)的操作。另外,我們還需要為每個(gè)租戶提供一個(gè)獨(dú)立的數(shù)據(jù)庫,以保證數(shù)據(jù)隔離性。

        六、小結(jié)回顧

        本文詳細(xì)介紹了如何使用Spring Boot和Spring Cloud實(shí)現(xiàn)一個(gè)支持多租戶部署的應(yīng)用。主要包括搭建Spring Boot和Spring Cloud環(huán)境、修改數(shù)據(jù)庫設(shè)計(jì)、實(shí)現(xiàn)應(yīng)用多租戶部署、實(shí)現(xiàn)租戶管理等方面。

        應(yīng)用場景主要包括SaaS應(yīng)用、多租戶云服務(wù)等。優(yōu)劣勢主要體現(xiàn)在提升了應(yīng)用的可擴(kuò)展性和可維護(hù)性,但也增加了部署和管理的復(fù)雜度。未來的改進(jìn)方向可以考慮進(jìn)一步提升多租戶管理的自動(dòng)化程度,減少人工干預(yù)和錯(cuò)誤率。

        ?? 歡迎加入小哈的星球 ,你將獲得: 專屬的項(xiàng)目實(shí)戰(zhàn) / Java 學(xué)習(xí)路線 / 一對(duì)一提問 / 學(xué)習(xí)打卡 /  贈(zèng)書福利


        全棧前后端分離博客項(xiàng)目 2.0 版本完結(jié)啦, 演示鏈接http://116.62.199.48/ ,新項(xiàng)目正在醞釀中。全程手摸手,后端 + 前端全棧開發(fā),從 0 到 1 講解每個(gè)功能點(diǎn)開發(fā)步驟,1v1 答疑,直到項(xiàng)目上線。目前已更新了239小節(jié),累計(jì)38w+字,講解圖:1645張,還在持續(xù)爆肝中.. 后續(xù)還會(huì)上新更多項(xiàng)目,目標(biāo)是將Java領(lǐng)域典型的項(xiàng)目都整一波,如秒殺系統(tǒng), 在線商城, IM即時(shí)通訊,Spring Cloud Alibaba 等等,戳我加入學(xué)習(xí),已有1300+小伙伴加入(早鳥價(jià)超低)



             
                

        1. 我的私密學(xué)習(xí)小圈子~

        2. 如何用 Java 幾分鐘處理完 30 億個(gè)數(shù)據(jù)?

        3. Nginx 的 5 大應(yīng)用場景,太實(shí)用了!

        4. 炫技Groovy!SpringBoot中的動(dòng)態(tài)編程實(shí)戰(zhàn)

        最近面試BAT,整理一份面試資料Java面試BATJ通關(guān)手冊(cè),覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。

        獲取方式:點(diǎn)“在看”,關(guān)注公眾號(hào)并回復(fù) Java 領(lǐng)取,更多內(nèi)容陸續(xù)奉上。

        PS:因公眾號(hào)平臺(tái)更改了推送規(guī)則,如果不想錯(cuò)過內(nèi)容,記得讀完點(diǎn)一下在看,加個(gè)星標(biāo),這樣每次新文章推送才會(huì)第一時(shí)間出現(xiàn)在你的訂閱列表里。

        點(diǎn)“在看”支持小哈呀,謝謝啦

        瀏覽 167
        10點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        10點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            亚洲乱论视频 | AV老鸭窝 | 大尺度真军露器官做爰未删减 | 欧美色播 12 18 | 皇帝骑带木马被大臣公开打 | h文婚纱店里被强 | 国产激情视频 | 奇米影视第四色7777 | 日本黄色视频在线播放 | 激情六月丁香 |