多租户系统的实现方式
一、多租户架构概述
多租户(Multi-Tenancy)是SaaS(软件即服务)模式的核心架构技术,允许多个租户(客户/组织)共享同一软件实例,同时保证数据隔离和安全。其核心价值在于:
- 资源高效利用:共享硬件/软件资源,降低运营成本
- 快速交付:新租户开通即用,无需重复部署
- 统一运维:集中管理版本更新与系统维护
- 按需扩展:根据租户规模动态调整资源
经典类比:
传统软件如同每家独立安装煤气罐;多租户如同共享天然气管道,按使用量付费。
二、数据隔离实现方案
1. 共享表模式(字段隔离)
实现原理
- 所有租户共享同一数据库实例和表结构
- 通过
tenant_id
字段逻辑隔离数据 - SQL自动追加租户过滤条件(如
WHERE tenant_id = 'T001'
)
技术实现(MyBatis-Plus示例)
// 租户拦截器实现
public class TenantInterceptor implements TenantLineHandler {@Overridepublic String getTenantIdColumn() {return "tenant_id"; // 数据库租户字段}@Overridepublic Expression getTenantId() {// 从请求上下文获取租户IDreturn new StringValue(TenantContext.getCurrentTenant()); }
}// 请求过滤器
@WebFilter("/*")
public class TenantFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {// 从Header获取租户IDString tenantId = ((HttpServletRequest)request).getHeader("X-Tenant-ID");TenantContext.setCurrentTenant(tenantId);chain.doFilter(request, response);}
}
优缺点
优点 | 缺点 |
---|---|
成本最低,资源利用率高 | 数据隔离性差(SQL注入风险) |
跨租户统计便捷 | 单表数据膨胀导致性能下降 |
新增租户无需重启 | 难以支持个性化表结构 |
适用场景:To C应用(问卷系统)、初创SaaS产品
2. 独立Schema模式
实现原理
租户共享数据库实例,但拥有独立Schema(PostgreSQL)或Database(MySQL)
物理隔离数据,表结构相同
通过动态切换Schema实现隔离
技术实现
-- 为租户创建独立Schema
CREATE SCHEMA tenant_T001;
CREATE TABLE tenant_T001.users (...);
// Spring动态数据源路由
public class TenantDataSourceRouter extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return "tenant_" + TenantContext.getTenantId(); // 返回Schema名称}
}
优缺点:
优点 | 缺点 |
---|---|
数据物理隔离 | 跨租户统计复杂 |
运维成本低于独立DB | 连接管理复杂 |
支持中等规模租户 | 租户数量受实例性能限制 |
适用场景:企业协作平台、中等规模ERP系统 |
3.独立数据库模式
实现原理
- 每个租户独占数据库实例
- 完全物理隔离,最高安全级别
- 支持深度定制化需求
技术实现:
// 动态数据源配置
@Configuration
public class DataSourceConfig {@Bean@ConfigurationProperties(prefix="datasource.tenant1")public DataSource tenant1DataSource() {return DataSourceBuilder.create().build();}@Beanpublic DataSource routingDataSource() {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("T001", tenant1DataSource());// 添加更多租户数据源...AbstractRoutingDataSource ds = new AbstractRoutingDataSource() {@Overrideprotected Object determineCurrentLookupKey() {return TenantContext.getTenantId();}};ds.setTargetDataSources(targetDataSources);return ds;}
}
优缺点:
优点 | 缺点 |
---|---|
最高级别数据安全 | 硬件和运维成本高 |
故障影响范围小 | 租户规模扩展困难 |
支持深度定制 | 跨租户操作复杂 |
适用场景:银行核心系统、医疗平台、政府政务云 |
4. 三种方案对比
维度 | 共享表模式 | 独立Schema模式 | 独立数据库模式 |
---|---|---|---|
隔离性 | 低(逻辑隔离) | 中(Schema隔离) | 高(物理隔离) |
成本 | 低 | 中 | 高 |
最大租户量 | 高(数千+) | 中(数百) | 低(数十) |
跨租户统计 | 简单 | 复杂 | 极难 |
运维难度 | 低 | 中 | 高 |
定制能力 | 弱 | 中 | 强 |
三、架构设计与扩展方案
1. 资源隔离模式
模式 | 核心特点 | 适用场景 |
---|---|---|
共享模式 | 所有租户共享计算/存储资源,需限流降级机制 | 成本敏感型业务(中小客户) |
竖井模式 | 每个租户独占资源(独立容器/VM),完全隔离 | 高安全需求场景(政府、金融) |
分域模式 | 混合架构:普通租户共享基础域,VIP租户使用专用域独立资源 | 兼顾成本与隔离的混合业务 |
技术栈:
容器编排:Kubernetes + Docker
部署管理:Helm Charts
服务网格:Istio(流量管理)
核心能力:
租户自动开通/注销(API驱动)
资源弹性伸缩(HPA)
健康监控与自愈(Prometheus+Alertmanager)
多版本并行发布(蓝绿部署)
四、 前端租户识别方案
1. 静态打包方案
实现:
为每个租户构建独立前端包
定制LOGO、主题色、功能模块
优缺点:
✅ 优点
- 高度品牌定制化
- 完全隔离无冲突
❌ 缺点
- 维护成本高(N个代码分支)
- 更新需重新打包部署
适用场景:大型企业客户、品牌独立性要求高的场景
2. 动态域名方案
实现:
// 根据域名识别租户
const tenantMap = {'clientA.com': 'T001','clientB.com': 'T002'
};const getTenantId = () => {const hostname = window.location.hostname;return tenantMap[hostname] || 'default';
};// 请求头自动注入租户ID
axios.interceptors.request.use(config => {config.headers['X-Tenant-ID'] = getTenantId();return config;
});// 动态加载租户配置
fetch(`/configs/${getTenantId()}.json`).then(res => res.json()).then(config => {document.documentElement.style.setProperty('--primary-color', config.themeColor);document.getElementById('logo').src = config.logoUrl;});
适用场景:标准化SaaS产品(如企业微信、钉钉)
五、选型关键因素
1.数据规模
海量小数据(<1GB/租户)→ 共享表模式
中大型数据集(1GB-1TB)→ 独立Schema
超大规模/敏感数据 → 独立数据库
2安全合规
GDPR/HIPAA等严格合规 → 独立数据库
ISO27001等商业认证 → 独立Schema
基础安全要求 → 共享表模式
3.成本预算
低成本优先(人均成本<¥100/月)→ 共享表模式
中等预算(¥100-500/月)→ 独立Schema
高预算(>¥500/月)→ 独立数据库
4.扩展需求
快速弹性扩展 → 容器化分域模式(K8s)
稳定优先 → 竖井模式
混合负载 → 分域模式
六、总结与建议
场景化推荐方案
演进趋势:
业务场景 | 推荐方案 | 典型案例 | 成本系数 |
---|---|---|---|
初创SaaS验证期 | 共享表模式+动态域名 | 轻量级CRM工具 | 1x |
中大型企业服务 | 独立Schema+分域架构 | 钉钉/企业微信 | 2-3x |
金融/医疗核心系统 | 独立数据库+容器竖井 | 银行信贷系统 | 5-8x |
混合型云平台 | 分域模式(基础域+专用域) | AWS Organizations | 3-5x |
- 容器化普及
Kubernetes大幅降低独立实例运维成本,租户隔离粒度从VM级细化到Pod级 - 数据隔离增强
数据库池化技术(如Vitess)提升Schema模式扩展性
加密技术(TDE+列加密)弥补共享表模式安全短板 - 智能调度
服务网格(Service Mesh)实现租户级流量管理:
按租户分配资源配额
故障租户自动熔断
SLA驱动的优先级调度 - 混合架构兴起
核心原则:没有最优方案,只有最适方案——根据业务阶段动态演进架构。初期优先共享模式验证市场,成长期采用分域架构平衡成本与隔离,成熟期通过混合方案满足差异化需求。
参考文章:
参考文章1
参考文章2
参考文章3
参考文章4