1. 多租户SaaS概述

1.1 多租户概念

多租户(Multi-Tenancy)是SaaS架构的核心特征,指单个软件实例同时服务于多个租户(Tenant),每个租户拥有独立的业务数据与配置,且彼此逻辑隔离。租户可以是企业、部门或个人用户,在鉴权拦截链路中,租户身份是路由与权限判定的第一要素。

关键定义: 多租户 ≠ 多用户。租户是资源隔离与计费的单位,用户是租户内的操作主体。鉴权拦截链路必须同时校验“租户有效性”与“用户权限”。

1.2 SaaS架构演进

SaaS架构经历了从单体到微服务的演进,不同阶段对鉴权拦截与链路追踪的要求差异显著:

阶段 架构特征 鉴权拦截方式 链路追踪难度
单体SaaS 单进程、共享数据库 Filter拦截器 + ThreadLocal 低(单进程内完成)
垂直拆分SaaS 按功能拆分为多个服务 网关统一鉴权 + 服务间Token传递 中(需跨服务传递上下文)
微服务SaaS 细粒度服务、独立部署 API Gateway + 分布式Session + JWT 高(需全链路追踪与异常捕获)
云原生SaaS 容器化、Service Mesh、可观测性 Sidecar代理 + OPA策略引擎 极高(需分布式追踪+日志+指标联动)
课程聚焦: 本课程以微服务SaaS与云原生SaaS为背景,重点解决鉴权拦截链路中异常捕获与分布式追踪的工程难题。

1.3 租户隔离模型

租户隔离模型决定了数据存储与资源分配策略,直接影响鉴权拦截链路的实现复杂度。主流模型分为三种:

  • 共享模型(Shared): 所有租户共用同一数据库实例与表结构,通过tenant_id字段区分。成本最低,但隔离性最弱,鉴权拦截需确保tenant_id不被篡改。
  • 独享模型(Isolated): 每个租户拥有独立的数据库实例或Schema。隔离性最强,但资源开销大,鉴权拦截需动态路由到对应数据源。
  • 混合模型(Hybrid): 根据租户等级或业务需求,部分租户共享、部分租户独享。鉴权拦截链路需支持动态隔离策略,在运行时判断租户所属模型。
租户隔离模型对比 共享模型 租户A: tenant_id=1001 租户B: tenant_id=1002 租户C: tenant_id=1003 同一数据库 · 同一表 独享模型 租户A → DB_A 租户B → DB_B 租户C → DB_C 独立数据库 · 独立Schema 混合模型 VIP租户 → 独享DB 普通租户 → 共享DB 动态路由策略 按需隔离 · 弹性伸缩

1.4 隔离模型选择矩阵

实际项目中,隔离模型的选择需综合安全等级、合规要求、运维成本与性能四个维度:

评估维度 共享模型 独享模型 混合模型
数据安全 低(依赖应用层隔离) 高(物理/逻辑隔离) 中高(按需分配)
合规满足 难(如GDPR、金融合规) 易(独立审计) 中(需策略配置)
运维成本 低(一套环境) 高(N套环境) 中(自动化编排)
查询性能 中(大表+索引) 高(小表+无干扰) 中高(按租户优化)
鉴权复杂度 低(统一Filter) 中(多数据源路由) 高(动态策略引擎)
常见陷阱: 共享模型下,若鉴权拦截链路未对tenant_id做服务端校验,攻击者可伪造租户身份越权访问其他租户数据。必须结合JWT签名与链路追踪日志双重验证。

1.5 鉴权拦截链路中的租户上下文传递

在微服务SaaS架构中,租户上下文(Tenant Context)需在鉴权拦截链路中透传。典型传递方式如下:

# 伪代码:租户上下文传递示例
class TenantContext:
    """线程级租户上下文"""
    _tenant_id = None
    _user_id = None

    @classmethod
    def set(cls, tenant_id: str, user_id: str):
        cls._tenant_id = tenant_id
        cls._user_id = user_id

    @classmethod
    def get_tenant_id(cls) -> str:
        return cls._tenant_id

# 鉴权拦截器
class AuthInterceptor:
    def intercept(self, request):
        token = request.headers.get('Authorization')
        payload = self.verify_jwt(token)  # 验证JWT
        TenantContext.set(payload['tenant_id'], payload['user_id'])
        # 继续链路...
鉴权拦截链路:租户上下文传递流程 客户端 API网关 JWT校验 鉴权服务 提取tenant_id 设置上下文 业务服务 使用tenant_id DB 链路追踪关键点 1. 网关层记录 tenant_id 到 Span 标签 2. 鉴权服务将 tenant_id 注入 Trace Context 3. 业务服务从 Span 中提取 tenant_id 用于数据隔离
最佳实践: 在微服务SaaS中,建议将tenant_id放入gRPC Metadata或HTTP Header(如 X-Tenant-ID),并在API网关层统一注入。链路追踪系统(如OpenTelemetry)会自动将Header中的租户信息关联到Span,实现全链路可观测。