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 场景中,配额冲突是故障域扩展的主要诱因。本课程后续章节将重点分析“配额冲突→资源争抢→租户级联故障”的传导路径。
SaaS vs PaaS 多租户隔离模型对比 SaaS 隔离模型 租户 A 应用实例 租户 B 应用实例 Schema A Schema B 共享数据库实例 PaaS 隔离模型 Namespace A Namespace B Pod / 容器 Pod / 容器 共享集群节点 SaaS 侧重数据隔离(Schema/DB),PaaS 侧重计算隔离(Namespace/容器),配额冲突风险逐级升高

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 低延迟,二进制高效 需拦截器支持

上下文传递的典型流程

  1. 入口拦截: API 网关或中间件从请求中提取 Tenant ID。
  2. 上下文绑定: 将 Tenant ID 注入到请求上下文(如 Go 的 context.WithValue 或 Java 的 ThreadLocal)。
  3. 配额校验: 服务层根据 Tenant ID 查询配额策略,判断是否允许操作。
  4. 数据路由: 数据访问层根据 Tenant ID 选择对应的 Schema、表或存储桶。
  5. 审计日志: 所有操作记录附带 Tenant ID,用于计量和故障追溯。
常见陷阱: 异步消息(MQ/Kafka)中丢失 Tenant ID 会导致配额校验失效,进而引发跨租户资源抢占。建议在消息体或消息头中显式携带租户上下文。
租户上下文传递流程 客户端请求 API 网关 服务 A 数据层 提取 Tenant ID → 注入上下文 → 传递至下游服务 → 路由至对应数据分区 上下文传递关键步骤: 1. 网关解析 X-Tenant-ID 或 JWT 中的 tenant_id 2. 通过 RPC 拦截器 / HTTP 中间件注入上下文 3. 服务间调用时自动传递,确保端到端租户可追溯

1.4 租户标识与配额故障域的关联

租户标识不仅是路由依据,更是故障域划分的边界。在配额冲突场景中,系统通过 Tenant ID 定位到具体的配额桶(Quota Bucket),当某个租户的配额耗尽时,故障域应被限制在该租户的上下文内,避免扩散到其他租户。

关键设计原则: 租户上下文传递的完整性 = 配额隔离的有效性。任何上下文丢失都可能导致配额检查失效,进而引发跨租户故障。