什么是多租户架构?
多租户架构有什么优势?
不同租户(比如不同企业)对功能的要求不一样。多租户架构支持为每个租户提供特定的配置和功能,比如某租户需要多语言支持,另一个租户需要独立报表统计,完全没问题。
统一维护一套代码,所有租户都能自动享受新版本带来的功能和优化。这就像升级了个操作系统,大家直接跟着享福利,程序员还省了很多事情。
传统多系统架构要为每个客户独立开发部署,工作量大得头秃。而多租户直接复用代码,少了重复开发,腰也不酸了。
多租户架构扩展起来很丝滑。新增一个租户?分分钟的事,不用额外改动主系统。
设计思路:我们怎么玩转多租户?
1. 架构选型
Spring Boot:轻量、快速、简单配置,Spring Boot天生就是为现代应用服务的。对于多租户,这更是优选,配置多数据源轻轻松松。 Spring Cloud:分布式必备,尤其是多租户 SaaS 服务,配合服务注册、发现和负载均衡,租户管理妥妥的。
2. 数据库设计
共享数据库模式:所有租户共用一个数据库,但通过字段(如 tenant_id
)来区分数据归属。这种模式对小型应用友好。独立数据库模式:每个租户一个独立数据库,数据隔离性更好,但运维成本高。适合大型租户或者对数据隔离要求高的业务。
3. 应用多租户部署
应用隔离:不同租户可能需要隔离在不同服务器上,或者通过容器(比如 Docker)独立运行。 应用配置:每个租户的配置可以通过配置中心管理(比如 Spring Cloud Config),灵活适配。
4. 租户管理
租户信息维护:我们需要一个租户管理服务,维护租户的基本信息,比如名称、套餐、到期时间等。 租户权限控制:不仅是数据,功能上也可以有区分,比如有的租户可以访问高级报表,有的只能看基础统计。
技术实现:Spring Boot 多租户架构怎么搞?
1. 多数据源实现
@Configuration
public class DataSourceConfig {
@Bean
@Primary
public DataSource dataSource() {
Map<Object, Object> targetDataSources = new HashMap<>();
// 添加多个数据源
targetDataSources.put("tenant1", createDataSource("jdbc:mysql://localhost:3306/tenant1"));
targetDataSources.put("tenant2", createDataSource("jdbc:mysql://localhost:3306/tenant2"));
// 动态路由数据源
AbstractRoutingDataSource routingDataSource = new AbstractRoutingDataSource() {
@Override
protected Object determineCurrentLookupKey() {
return TenantContext.getCurrentTenant();
}
};
routingDataSource.setTargetDataSources(targetDataSources);
routingDataSource.setDefaultTargetDataSource(createDataSource("jdbc:mysql://localhost:3306/default"));
return routingDataSource;
}
private DataSource createDataSource(String url) {
DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.url(url);
dataSourceBuilder.username("root");
dataSourceBuilder.password("password");
return dataSourceBuilder.build();
}
}
** AbstractRoutingDataSource
**:动态路由的核心。根据当前租户ID动态切换数据源。** TenantContext
**:上下文里存储当前租户信息,关键在于如何正确地获取和设置。
2. API层的多租户机制
tenant_id
,并设置到上下文中。@Component
public class TenantInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String tenantId = request.getHeader("X-Tenant-ID");
if (tenantId != null) {
TenantContext.setCurrentTenant(tenantId);
}
return true;
}
}
应用场景:多租户架构能干啥?
私有云环境:企业内部多个子部门共享一个 SaaS 系统。 公有云环境:服务于不同客户的 SaaS 服务,比如 CRM、ERP。 企业级应用:对租户进行严格权限和数据隔离,提升安全性和可靠性。
对编程、职场感兴趣的同学,可以链接我,微信:coder301 拉你进入“程序员交流群”。