SpringCloud + MybatisPlus:多租户模式与实现
一、多租户的基本概念
多租户(Multi-Tenancy) 是指在一套软件系统中,多个租户(客户)共享相同的基础设施和应用程序,但数据和配置相互隔离的架构模式。其核心目标是 降低成本 和 保证数据安全。
核心特点:
- 资源共享:租户共享服务器、数据库、代码等资源。
- 数据隔离:通过技术手段确保租户间数据不泄露。
- 配置独立:支持租户自定义配置(如界面、流程)。
隔离级别:
- 行级隔离:同一表中通过
tenant_id
字段区分(共享Schema模式)。 - Schema级隔离:同一数据库下不同Schema(共享数据库独立Schema模式)。
- 数据库级隔离:每个租户独立数据库(独立数据库模式)。
二、Spring Cloud集成MyBatis-Plus实现多租户
Spring Cloud与MyBatis-Plus结合实现多租户,需解决 租户ID传递、SQL自动过滤、数据填充 三个核心问题。
1. 核心组件集成
- API网关(Spring Cloud Gateway):从请求头/Token中提取租户ID,并向下游传递。
- 上下文传递:通过
ThreadLocal
在微服务间传递租户ID。 - MyBatis-Plus插件:自动在SQL中注入租户过滤条件。
- Feign客户端:跨服务调用时传递租户ID到请求头。
2. 租户ID全链路传递实现
(1)Spring Cloud Gateway过滤器(JwtTenantFilter)
通过GlobalFilter
解析JWT并将租户ID存入上下文:
@Component
public class JwtTenantFilter implements GlobalFilter, Ordered {private final JwtUtils jwtUtils;public JwtTenantFilter(JwtUtils jwtUtils) {this.jwtUtils = jwtUtils;}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1. 从请求头获取JWT(格式:Bearer {token})String authHeader = exchange.getRequest().getHeaders().getFirst("Authorization");if (authHeader == null || !authHeader.startsWith("Bearer ")) {return handleMissingToken(exchange);}String token = authHeader.substring(7);try {// 2. 解析JWT获取tenantIDString tenantId = jwtUtils.getTenantIdFromToken(token);if (tenantId == null) {return handleInvalidTenant(exchange);}// 3. 将tenantID存入上下文(关键点!)TenantContextHolder.setTenantId(tenantId);// 4. 添加X-Tenant-ID到请求头,传递给下游服务ServerHttpRequest newRequest = exchange.getRequest().mutate().header("X-Tenant-ID", tenantId).build();// 5. 请求结束后清除上下文,防止内存泄漏return chain.filter(exchange.mutate().request(newRequest).build()).doFinally(signal -> TenantContextHolder.clear());} catch (JwtValidationException e) {return handleJwtError(exchange, e);}}