Spring Boot 优雅实现多租户架构,so easy~!

点击关注公众号,Java干货及时送达7fb84ad3d8e9050333d1f64034497868.png

bb2ecf32835244d71a633dcc3a49bb18.png 国内最强微服务框架,没有之一!

e71b1b451a922d2b56df5fd2a033f511.png 几乎覆盖 Spring Boot 所有操作!

一、概述

1.什么是多租户架构?

多租户架构是指在一个应用中支持多个租户(Tenant)同时访问,每个租户拥有独立的资源和数据,并且彼此之间完全隔离。

通俗来说,多租户就是把一个应用按照客户的需求“分割”成多个独立的实例,每个实例互不干扰。

2. 多租户架构的优势

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

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

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

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

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

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

二、设计思路

1. 架构选型

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

1.1 Spring Boot

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

Spring Boot 基础就不介绍了,推荐看这个实战项目:

https://github.com/javastacks/spring-boot-best-practice

@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等,以实现服务发现、负载均衡等微服务功能。

另外,如果你近期准备面试跳槽,建议在Java面试库小程序在线刷题,涵盖 2000+ 道 Java 面试题,几乎覆盖了所有主流技术面试题。

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 {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/api/tenant/**").hasRole("ADMIN").anyRequest().authenticated().and().formLogin();}@Autowiredpublic 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中可以通过多数据源和动态路由来实现多租户机制。

Spring Boot 基础就不介绍了,推荐看这个实战项目:

https://github.com/javastacks/spring-boot-best-practice

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 {@Overrideprotected 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项目中引入以下依赖:

<!-- 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中配置相应的参数,如下所示:

spring:datasource:url: jdbc:mysql://localhost:3306/appdb?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456mybatis:type-aliases-package: com.example.demo.modelmapper-locations: classpath:mapper/*.xmlserver:port: 8080eureka: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。

Java指南:java-family.cn

2. 修改数据库设计

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

3. 实现应用多租户部署

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

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

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

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

4. 实现租户管理

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

六、小结回顾

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

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

版权声明:本文为CSDN博主「格林希尔」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/u010349629/article/details/130737253


最后推荐下我的《Spring Boot 核心技术课》,几乎覆盖 Spring Boot 所有核心知识点,一次付费,永久学习…

感兴趣的扫码联系订阅学习:

95bd84772098b4f7416f830b5fca3f30.png

End

6d0059f6405aa19773a96b4b37912c9d.png 国内最强微服务框架,没有之一!

20a2cf75f48d3fa8f38d116c6e0fd956.png 几乎涵盖 Spring Boot 所有操作!

3f374a473825b676355c318b6445faec.png 用上 ChatGPT 啦,强的离谱!

1459649bf36f7321a40653db25103f49.png ChatGPT 视频课程来了,完全免费!

ba111ebac7cbb0edb9a675f4c8f613a9.png Java 20 正式发布,超神了。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/61146.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jenkins + Docker 一键自动化部署 Spring Boot 项目,步骤齐全,少走坑路!

点击关注公众号&#xff0c;Java干货及时送达 国内最强微服务框架&#xff0c;没有之一&#xff01; 几乎覆盖 Spring Boot 所有操作&#xff01; 本文章实现最简单全面的 Jenkinsdockerspringboot 一键自动部署项目&#xff0c;步骤齐全&#xff0c;少走坑路。 环境&#xff1…

MyBatis-Plus 可视化代码生成器来啦,让你的开发效率大大提速!!

点击关注公众号&#xff0c;Java干货及时送达 学习 Spring Cloud 微服务的正确姿势&#xff01; 用上 ChatGPT 啦&#xff0c;强的离谱&#xff01; 终于把 Spring Boot 3.0 写成书了&#xff01; 前言 在基于Mybatis的开发模式中&#xff0c;很多开发者还会选择Mybatis-Plus来…

农民工与学生为楼癫狂 富人加速撤离

首先是各级政府不约而同开始鼓励农民工进城买房。然后&#xff0c;国家信息中心宏观经济形势课题组的报告&#xff0c;甚至把这件事提高到了生死攸关的高度&#xff1a;农民工市民化&#xff0c;是消化住宅库存的关键环节和成败所在。特别想请教国家信息中心宏观经济形势课题组…

计算机成下一个土木了??

来源&#xff1a;知乎 最近互联网裁员&#xff0c;有网友热议&#xff1a;2022年大规模裁员后&#xff0c;计算机专业会不会成为下一个土木&#xff1f; 前些年抓住了互联网行业的红利期&#xff0c;进入大厂的员工&#xff0c;基本可以实现在一线城市买房扎根。 但反观现在&am…

读书笔记-大颠狂(非同寻常的大众幻想与群众性癫狂)

本书内容概要 《财富》杂志鼎力推荐的75本商务必读书之一&#xff0c;《金融时报》评选的史上最佳10部金融作品之一。本书在金融史上的地位不言自喻&#xff0c;在世界各地流传了近200年依然畅销不衰。它不单是一本金融投资领域的超级经典&#xff0c;也是一部有关人类愚行的编…

让人癫狂的24号,请你慢点离开

那一年&#xff0c;你18岁&#xff0c;初进联盟&#xff0c;受世人怀疑&#xff0c;拿下扣篮冠军  那一年&#xff0c;你19岁&#xff0c;史上ALL STAR首发&#xff0c;惊艳世人  那一年&#xff0c;你20岁&#xff0c;坐稳球队先发&#xff0c;场均19&#xff0c;成为一股…

IntelliJ IDEA 2019,从入门到癫狂,图文教程

点击上方“小哈学Java”&#xff0c;选择“星标” 回复“666”&#xff0c;领取100G独家整理的学习资料哟~ 来源&#xff1a;http://t.cn/Eiv6CTU 如果说IntelliJ IDEA是一款现代化智能开发工具的话&#xff0c;Eclipse则称得上是石器时代的东西了。 其实笔者也是一枚从Eclipse…

IntelliJ IDEA 2019从入门到癫狂 图文教程!

点击上方“方志朋”&#xff0c;选择“设为星标” 回复”666“获取新整理的面试资料 作者&#xff1a;yizhiwazi 来源&#xff1a;www.jianshu.com/p/9c65b7613c30 前言&#xff1a;IntelliJ IDEA 如果说IntelliJ IDEA是一款现代化智能开发工具的话&#xff0c;Eclipse则称得上…

新世纪的群众性幻想与癫狂3

又泡沫的地方&#xff0c;就有财富的地方 自我意淫的人造牛市 进入2015年以来&#xff0c;静默已久的A股股价就出现了一个令人意想不到的暴涨。到2015年6月中旬&#xff0c;上证综指已较2014年7月上涨了152%、较年初上涨了59.7%&#xff0c;中小企业板、创业板较年初更是上涨了…

癫狂的dom——利用css3让dom动起来

不废话&#xff0c;先来看一下效果&#xff1a; 下面上代码&#xff1a; html部分&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title></title><link href"shake.css" …

IntelliJ IDEA 2019从入门到癫狂

前言&#xff1a;IntelliJ IDEA 如果说IntelliJ IDEA是一款现代化智能开发工具的话&#xff0c;Eclipse则称得上是石器时代的东西了。 其实笔者也是一枚从Eclipse转IDEA的探索者&#xff0c;随着近期的不断开发实践和调试&#xff0c;逐步体会到这款智能IDE带来的巨大开发便利…

新世纪的群众性幻想与癫狂

历史不会改变&#xff0c;只会一次次的重复 经过了千万年的进化&#xff0c;人类已经站在了食物链的顶端。人类的进化并不是肢体或皮毛上演化所带来的结果&#xff0c;而是人类具有智慧&#xff0c;知道使用大脑去思考判断。但是&#xff0c;人毕竟还是动物&#xff0c;内心所保…

IntelliJ IDEA 2019从入门到癫狂 图文教程

点击上方“朱小厮的博客”&#xff0c;选择“设为星标” 做积极的人&#xff0c;而不是积极废人 来源&#xff1a;http://t.cn/Eiv6CTU 前言&#xff1a;IntelliJ IDEA 如果说IntelliJ IDEA是一款现代化智能开发工具的话&#xff0c;Eclipse则称得上是石器时代的东西了。 其实笔…

CXO是什么?医药板块龙头都有哪些?

制药行业是当今最复杂、监管最严格的行业之一。新药的开发&#xff0c;从最初的发现到最终的批准&#xff0c;是一个漫长而昂贵的过程&#xff0c;需要许多不同专业人士的专业知识。而制药公司面临的主要挑战之一是平衡创新需求与成本效率需求&#xff0c;面对这个挑战&#xf…

医疗器械上市公司

内在上交所和深交所上市的公司中&#xff0c;主营业务为医疗器械的一共有35家&#xff0c;在港交所上市的有8家&#xff0c;共计43家。 图片来自“123RF图库” 医疗器械、药品和医疗服务并称为医疗行业的三驾马车。国家政策的支持&#xff0c;市场容量的扩张&#xff0c;无疑…

全网盘点有哪些免费开源提高生产力的 GitHub 项目火了?

全网盘点有哪些免费开源提高生产力的 GitHub 项目火了&#xff1f; 开箱即用的地理信息系统 「地理信息系统&#xff08;Geographic Information System&#xff0c;简称 GIS&#xff09;」是一种用于采集、存储、处理、分析、管理和展示地理信息的计算机系统。 简单来说&…

科普:生成式 AI 简介

What I cannot create, I do not understand. - Richard Feynman 前言 你左拥右抱着 Stable Diffusion 和 MidJourney 创造美轮美奂的图片。 你熟练使用着 ChatGPT 和 LLaMa 创造辞致雅赡的文字。 你来回切换着 MuseNet 和 MuseGAN 创造高山流水的音乐。 毋庸置疑&#xff0c;人…

生成式 AI 简介

What I cannot create, I do not understand. - Richard Feynman 前言 你左拥右抱着 Stable Diffusion 和 MidJourney 创造美轮美奂的图片。 你熟练使用着 ChatGPT 和 LLaMa 创造辞致雅赡的文字。 你来回切换着 MuseNet 和 MuseGAN 创造高山流水的音乐。 毋庸置疑&#xff0c;人…

如何编写AI艺术提示[示例+模板]

有没有觉得制作 AI 艺术提示需要秘密和魔法&#xff1f;当您的所有提示都失败时&#xff0c;所有这些创意专业人士如何在Midjourney和DALL-E等工具中创建令人惊叹的&#xff0c;令人兴奋的视觉效果&#xff1f; 现实情况是&#xff0c;创建很酷的AI艺术提示并不像看起来那么复…

2天300+作品,Midjourney将彻底颠覆食品包装设计!

Midjourney设计的“世界最可爱的零食包装 原本是为了提高效率让短视频团队去研究AI&#xff0c;结果我自己却陷进了Midjourney&#xff08;AI绘画工具&#xff09;&#xff0c;连玩一周。可以说&#xff0c;Midjourney给我在图片领域带来的震撼&#xff0c;以及它将对设计领域的…