网易首页 > 网易号 > 正文 申请入驻

优雅掌握SpringBoot多租户架构,轻松应对复杂业务场景

0
分享至

Java精选面试题 (微信小程序): 5000+ 道面试题和选择题, 真实面经 , 简历模版 ,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计、大厂真题等,在线随时刷题!
一、概述
1 什么是多租户架构?

多租户架构是指在一个应用中支持多个租户(Tenant)同时访问,每个租户拥有独立的资源和数据,并且彼此之间完全隔离。通俗来说,多租户就是把一个应用按照客户的需求“分割”成多个独立的实例,每个实例互不干扰。

2 多租户架构的优势

  • 更好地满足不同租户的个性化需求。

  • 可以降低运维成本,减少硬件、网络等基础设施的投入。

  • 节约开发成本,通过复用代码,快速上线新的租户实例。

  • 增强了系统的可扩展性和可伸缩性,支持水平扩展,每个租户的数据和资源均可管理和控制。

3 实现多租户架构的技术选择

对于实现多租户架构技术不是最重要的最重要的是正确的架构思路。但是选择正确的技术可以更快地实现多租户架构。

二、设计思路 1 架构选型

基于Java开发多租户应用推荐使用Spring Boot和Spring Cloud。Spring Boot能快速搭建应用并提供许多成熟的插件。Spring Cloud则提供了许多实现微服务架构的工具和组件。

1.1 Spring Boot

使用Spring Boot可以简化项目的搭建过程自动配置许多常见的第三方库和组件,减少了开发人员的工作量。

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

在架构多租户的系统时Spring Cloud会更加有用。Spring Cloud提供了一些成熟的解决方案,如Eureka、Zookeeper、Consul等,以实现服务发现、负载均衡等微服务功能。

推荐划水摸鱼地址: https://www.yoodb.com/slack-off/home.html
2 数据库设计

在多租户环境中数据库必须为每个租户分别存储数据并确保数据隔离。我们通常使用以下两种方式实现:

  • 多个租户共享相同的数据库,每个表中都包含tenant_id这一列,用于区分不同租户的数据。

  • 为每个租户创建单独的数据库,每个数据库内的表结构相同,但数据相互隔离。

3 应用多租户部署

为了实现多租户在应用部署时我们需要考虑以下两个问题。

3.1 应用隔离

在多租户环境中不同租户需要访问不同的资源,因此需要进行应用隔离。可以通过构建独立的容器或虚拟机、使用命名空间等方式实现。Docker就是一种非常流行的隔离容器技术。

3.2 应用配置

由于每个租户都有自己的配置需求因此需要为每个租户分别设置应用配置信息,例如端口号、SSL证书等等。这些配置可以存储在数据库中,也可以存储在云配置中心中。

4 租户管理

在多租户系统中需要能够管理不同租户的数据和资源,同时需要为每个租户分配相应的权限。解决方案通常包括以下两部分。

4.1 租户信息维护

租户信息的维护包括添加、修改、删除、查询等操作,要求能够根据租户名称或租户ID快速查找对应的租户信息。

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 租户权限控制

在多租户应用中必须为每个租户分别设置对系统资源的访问权限。例如,A租户和B租户不能访问彼此的数据。

@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");  
    }  
}
三、技术实现 1 Spring Boot中的多租户实现

在Spring Boot中可以通过多数据源和动态路由来实现多租户机制。

1.1 多数据源实现

多数据源是指为不同的租户配置不同的数据源,使得每个租户都可以访问自己的独立数据。具体实现方法如下:

@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();  
    }  
}  

以上代码是配置了三个数据源分别对应三个租户。然后在使用时,可以使用注解标记需要连接的数据源。

@Service  
public class ProductService {  
    @Autowired  
    @Qualifier("dataSourceA")  
    private DataSource dataSource;  
  
     // ...   
}  
1.2 动态路由实现

动态路由是指根据请求的URL或参数动态地切换到对应租户的数据源。具体实现如下:

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();  
    }  
}  

以上是动态路由的核心代码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 groupId>       

 spring-boot-starter-web artifactId>   dependency>         

        

 org.springframework.cloud groupId>       

 spring-cloud-dependencies artifactId>       

 2020.0.3 version>       

 pom type>       

 import scope>   dependency>  








然后需要在application.yml中配置相应的参数,如下所示:

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为数据库连接的URL,username和password为数据库连接的账号和密码;server.port为Spring Boot应用启动的端口;eureka.client.serviceUrl.defaultZone为Eureka服务注册中心的URL。

2 修改数据库设计

接下来需要对数据库进行相应的修改,以支持多租户部署。具体来说,我们需要在数据库中添加一个与租户相关的字段,以便在应用中区分不同的租户。

3 实现应用多租户部署

接着需要在代码中实现应用的多租户部署功能。具体来说,我们需要为每个租户实例化对应的Spring Bean,并根据租户ID将请求路由到相应的Bean中去处理。

以下是一个简单的实现示例:

@Configuration  
public class MultiTenantConfig {  
   
     // 提供对应租户的数据源   
    @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();  
    }  
   
     // 动态切换租户   
    @Bean  
    public MultiTenantInterceptor multiTenantInterceptor(TenantResolver tenantResolver) {  
        MultiTenantInterceptor interceptor = new MultiTenantInterceptor();  
        interceptor.setTenantResolver(tenantResolver);  
        return interceptor;  
    }  
   
     // 注册拦截器   
    @Override  
    public void addInterceptors(InterceptorRegistry registry) {  
        registry.addInterceptor(multiTenantInterceptor());  
    }  
   
     // 注册租户信息   
    @Bean  
    public TenantRegistry tenantRegistry() {  
        return new TenantRegistryImpl();  
    }  
       
     // 解析租户ID   
    @Bean  
    public TenantResolver tenantResolver() {  
        return new HeaderTenantResolver();  
    }  
   
}  

其中MultiTenantConfig是多租户部署的核心配置类,它提供了对应租户数据源、多租户Session工厂、动态切换租户等功能。

4 实现租户管理

最后需要实现一个租户管理的功能,以便在系统中管理不同的租户。具体来说,我们可以使用Spring Cloud的服务注册与发现组件Eureka来注册每个租户的实例,并在管理界面中进行相应的操作。另外,我们还需要为每个租户提供一个独立的数据库,以保证数据隔离性。

六、小结回顾

本文详细介绍了如何使用Spring Boot和Spring Cloud实现一个支持多租户部署的应用。主要包括搭建Spring Boot和Spring Cloud环境、修改数据库设计、实现应用多租户部署、实现租户管理等方面。

应用场景主要包括SaaS应用、多租户云服务等。优劣势主要体现在提升了应用的可扩展性和可维护性,但也增加了部署和管理的复杂度。未来的改进方向可以考虑进一步提升多租户管理的自动化程度,减少人工干预和错误率。

作者:格林希尔 来源:https://blog.csdn.net/u010349629/article/details/130737253

公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

最近有很多人问,有没有技术或摸鱼交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!在线摸鱼:https://www.yoodb.com/

Java精选面试题(微信小程序):3000+道面试题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等,在线随时刷题!

特别推荐:专注分享最前沿的技术与资讯,为弯道超车做好准备及各种开源项目与高效率软件的公众号,「大咖笔记」,专注挖掘好东西,非常值得大家关注。点击下方公众号卡片关注

文章有帮助的话,点在看,转发吧!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
林志颖捂了12年的kimi,首次公开正面照,网友:这脸,判若俩人……

林志颖捂了12年的kimi,首次公开正面照,网友:这脸,判若俩人……

可读
2026-06-25 23:21:52
台湾退役中将:张学良被软禁一点不冤,西安近乎打光蒋奉化御林军

台湾退役中将:张学良被软禁一点不冤,西安近乎打光蒋奉化御林军

磊子讲史
2026-06-29 15:34:11
狗主嫌狗打闹解开狗绳 两只比特犬将路人撕咬致死 因犯过失致人死亡罪一审获缓刑

狗主嫌狗打闹解开狗绳 两只比特犬将路人撕咬致死 因犯过失致人死亡罪一审获缓刑

红星新闻
2026-06-29 15:12:08
人老了要不要把存款交给子女?律师、银行从业者统一劝诫:守住钱

人老了要不要把存款交给子女?律师、银行从业者统一劝诫:守住钱

今日搞笑分享
2026-06-29 17:39:00
暴雨蓝色预警!四川局地将有雷暴大风或冰雹!

暴雨蓝色预警!四川局地将有雷暴大风或冰雹!

掌上金牛
2026-06-29 13:50:02
梅西为啥35岁后,开始爆世界杯进球?

梅西为啥35岁后,开始爆世界杯进球?

张佳玮写字的地方
2026-06-29 18:06:01
韩国史上最大规模产业投资计划!五年内DRAM产能翻倍,三星、SK海力士各新建两座芯片厂

韩国史上最大规模产业投资计划!五年内DRAM产能翻倍,三星、SK海力士各新建两座芯片厂

华尔街见闻官方
2026-06-29 14:26:36
冯小刚导演的《抓特务》为何受到冷落?孙玉良:宣传导向出了问题

冯小刚导演的《抓特务》为何受到冷落?孙玉良:宣传导向出了问题

孙玉良
2026-06-28 08:43:41
太阳黄蜂达成3换3交易,火箭迎来利好,杰伦格林或再次换队

太阳黄蜂达成3换3交易,火箭迎来利好,杰伦格林或再次换队

富贵体坛说
2026-06-29 11:00:53
4-2横扫张本智和!19岁国乒天才连斩5大世界名将,一战封神

4-2横扫张本智和!19岁国乒天才连斩5大世界名将,一战封神

小琴动漫
2026-05-30 14:30:26
本轮强降雨将在30日白天逐渐减弱结束 未来7天重庆无明显降水

本轮强降雨将在30日白天逐渐减弱结束 未来7天重庆无明显降水

上游新闻
2026-06-29 12:54:11
走个面真不容易!冯小刚《抓特务》破亿后大V宣发走起

走个面真不容易!冯小刚《抓特务》破亿后大V宣发走起

乡野小珥
2026-06-29 17:25:19
中际旭创跌超6% 成交额超300亿元

中际旭创跌超6% 成交额超300亿元

每日经济新闻
2026-06-29 13:30:09
不统而统!社科院专家首提新概念,或成两岸统一“第三条路”?

不统而统!社科院专家首提新概念,或成两岸统一“第三条路”?

世界更加宽广
2026-06-28 14:09:04
“月捐人”终于被重视!韩红基金会首次致谢,救护车上也标注字样

“月捐人”终于被重视!韩红基金会首次致谢,救护车上也标注字样

火山詩话
2026-06-29 09:40:51
鲍鹏山:如果中国真的足够强大!我们没必要脆弱到那么害怕批评!

鲍鹏山:如果中国真的足够强大!我们没必要脆弱到那么害怕批评!

用冷眼洞悉世界
2026-06-24 00:44:14
表面老艺术家,私下贪财又好色,这几位晚节不保一点都不冤

表面老艺术家,私下贪财又好色,这几位晚节不保一点都不冤

梦史
2026-06-20 17:12:58
解忧 | 女子遭孩童掀开试衣帘,致全身裸露被多名男性围观

解忧 | 女子遭孩童掀开试衣帘,致全身裸露被多名男性围观

新民周刊
2026-06-28 20:11:48
原来他俩已离婚,如今一个在日本孤独终老,一个在上海娶将军之女

原来他俩已离婚,如今一个在日本孤独终老,一个在上海娶将军之女

胡一舸南游y
2026-06-28 23:00:49
凌晨没回家长消息被骂"装什么装",老师第二天搬出法条,网友炸了

凌晨没回家长消息被骂"装什么装",老师第二天搬出法条,网友炸了

教育人看世界
2026-06-25 21:23:27
2026-06-29 18:52:50
Java精选
Java精选
一场永远也演不完的戏
1795文章数 3859关注度
往期回顾 全部

科技要闻

杀疯了!深圳一天出两家200亿具身智能公司

头条要闻

媒体:台军偷拍福建舰 还异想天开用几款导弹摧毁航母

头条要闻

媒体:台军偷拍福建舰 还异想天开用几款导弹摧毁航母

体育要闻

他和伊朗队,再次赢得全世界的尊重

娱乐要闻

跟风电影《给阿公的牛肉丸》开机

财经要闻

近20家半导体企业开启新一轮涨价潮

汽车要闻

全新宝马iX3长轴版将于成都车展预售 四季度交付

态度原创

亲子
教育
旅游
艺术
公开课

亲子要闻

两岁宝宝上托二班,听老师讲故事时非常认真,网友:这个专注力真的太强了

教育要闻

都是体育运动,有什么内在联系呢

旅游要闻

仙游通报刺刀峡谷5人溺亡称尚未开放!曾将该地推荐为打卡点

艺术要闻

24幅 当代画家人物油画作品

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版