1. 多租户架构基础
1.1 多租户概念
多租户(Multi-Tenancy)是一种软件架构模式,允许单个软件实例同时服务多个租户(Tenant),同时为每个租户提供逻辑或物理上的隔离。租户可以是一个组织、一个项目组或一个业务单元,拥有独立的用户、配置、数据和资源视图。
核心特征: 共享基础设施 + 逻辑隔离 + 按租户计量 → 降低运营成本,提升资源利用率。
多租户架构的关键指标包括:
| 指标 | 说明 | 典型值 |
|---|---|---|
| 租户密度 | 单个实例承载的租户数量 | 100 ~ 100,000+ |
| 隔离粒度 | 数据/计算/网络的隔离层级 | Schema / 进程 / 虚拟机 |
| 配额维度 | CPU、内存、存储、API 调用 | 按租户 / 按项目 / 按用户 |
| 故障半径 | 单个租户故障影响范围 | ≤ 该租户自身 |
1.2 租户隔离模型:SaaS vs PaaS
隔离模型决定了租户之间共享与隔离的边界。SaaS 和 PaaS 在隔离策略上有本质差异:
| 维度 | SaaS 多租户 | PaaS 多租户 |
|---|---|---|
| 租户定义 | 使用应用的客户组织 | 部署应用的开发团队/项目 |
| 隔离层级 | 应用层 + 数据层(Schema/DB) | 集群层 + 命名空间(Namespace) |
| 资源配额 | 按订阅计划(用户数/存储量) | 按计算/网络/存储资源池 |
| 故障域 | 应用实例级别 | Pod / 容器 / 节点级别 |
| 典型场景 | CRM、ERP、协作工具 | Kubernetes、云函数、中间件 |
| 配额冲突风险 | 低(按计划硬限制) | 高(共享资源争抢) |
实践建议: 在 PaaS 场景中,配额冲突是故障域扩展的主要诱因。本课程后续章节将重点分析“配额冲突→资源争抢→租户级联故障”的传导路径。
1.3 租户标识与上下文传递
在多租户系统中,每个请求必须携带租户标识(Tenant ID),系统据此路由到正确的隔离域并执行配额检查。租户上下文的传递方式直接影响架构的复杂度和性能。
常见租户标识传递方式
| 方式 | 载体 | 优点 | 缺点 |
|---|---|---|---|
| HTTP Header | X-Tenant-ID |
无侵入,网关层可解析 | 需中间件统一提取 |
| JWT Claim | tenant_id |
自带签名,防篡改 | 体积增大 |
| 子域名 | tenant-a.example.com |
DNS 层路由,天然隔离 | 证书管理复杂 |
| 路径前缀 | /api/tenant-a/ |
简单直观 | URL 设计受限 |
| gRPC Metadata | tenant-id |
低延迟,二进制高效 | 需拦截器支持 |
上下文传递的典型流程
- 入口拦截: API 网关或中间件从请求中提取 Tenant ID。
- 上下文绑定: 将 Tenant ID 注入到请求上下文(如 Go 的
context.WithValue或 Java 的ThreadLocal)。 - 配额校验: 服务层根据 Tenant ID 查询配额策略,判断是否允许操作。
- 数据路由: 数据访问层根据 Tenant ID 选择对应的 Schema、表或存储桶。
- 审计日志: 所有操作记录附带 Tenant ID,用于计量和故障追溯。
常见陷阱: 异步消息(MQ/Kafka)中丢失 Tenant ID 会导致配额校验失效,进而引发跨租户资源抢占。建议在消息体或消息头中显式携带租户上下文。
1.4 租户标识与配额故障域的关联
租户标识不仅是路由依据,更是故障域划分的边界。在配额冲突场景中,系统通过 Tenant ID 定位到具体的配额桶(Quota Bucket),当某个租户的配额耗尽时,故障域应被限制在该租户的上下文内,避免扩散到其他租户。
关键设计原则: 租户上下文传递的完整性 = 配额隔离的有效性。任何上下文丢失都可能导致配额检查失效,进而引发跨租户故障。