跳至正文
Starone

解决方案

为隔离与规模而设计的多租户 SaaS 平台

我们构建 SaaS 产品之下的平台:租户模型、身份、计费、开通和发布机制。正是这些决定了产品能否像服务第一位客户那样,安全地服务第一百位客户。

问题域

一个 SaaS 产品其实是两套系统。一套是客户看到的应用。另一套是平台:它开通租户、认证用户、执行套餐限制、计量用量、出具账单,并把每个租户的数据与其他租户分隔开。第二套系统很少出现在路线图上,却决定着单位经济模型、企业级就绪程度,以及增长过程会有多痛苦。

最基础的决策是租户模型。在池化(pool)模型中,所有租户共享计算与存储,效率高、运维简单,但要求严格的逻辑隔离。在独立(silo)模型中,每个租户拥有专属资源,隔离性好,运行和发布成本更高。桥接(bridge)模型把两者结合起来,常见做法是共享计算、分库或分 schema,或者标准套餐使用池化基础设施、最大的客户使用专属技术栈。每一种选择都会影响成本、合规沟通、吵闹邻居风险和部署复杂度。

我们在设计平台时,让租户模型的决策明确、由代码强制执行,并在合理可行的范围内可以回退。租户上下文在边缘处一次性确立,并贯穿每一个服务、查询、缓存键、队列消息和日志行。平台中的其他一切,都建立在这一保证之上。

难在哪里

工程挑战

01

依赖开发者自觉的租户隔离

如果隔离靠的是每条查询都记得加上租户过滤条件,那么漏掉一个子句,就会把一个客户的数据暴露给另一个客户。这是 SaaS 产品可能出现的破坏性最大的故障。隔离必须在应用代码之下强制执行,通过行级安全、限定范围的凭证或独立存储来实现,使遗漏过滤条件时返回的是空结果,而不是全部数据。

02

吵闹邻居

在共享基础设施中,某个租户的批量导入或失控的报表可能耗尽数据库连接,拖慢所有其他租户的服务。如果没有按租户的限流、配额和工作负载分离,最大客户的行为就决定了最小客户的体验。

03

企业级身份要求

企业买家期望 SAML 或 OIDC 单点登录、SCIM 账号同步、强制多因素认证,以及来自其目录的角色映射。在自建的用户名密码表上事后补齐这些能力,既慢又容易出错,而且往往会在采购评审阶段成为阻碍。

04

与账单对不上的计量

按用量定价要求每一个计费事件恰好被计数一次。高负载下丢失的事件、重试时重复计数的事件,或者归到错误账期的事件,都会产生让客户提出异议的账单。计量首先是一个数据完整性问题,其次才是计费集成问题。

05

面向众多租户的发布

一次锁住大表的 schema 迁移,会让所有租户同时离线。租户独立部署时,问题则反过来:数百套技术栈逐渐漂移到不同版本。两种情况都需要经过设计的发布方案,涵盖向后兼容的迁移、渐进式发布和自动化的机群管理。

06

缺少按租户的健康视图

聚合仪表盘掩盖了某个租户的请求已经失败一小时的事实。支持团队答不上客户的问题,工程团队也分不清是平台故障还是租户自身的问题。遥测数据必须从第一个请求开始就携带租户标识。

我们如何构建

架构

平台拆分为管理租户的控制平面和服务租户的数据平面。租户上下文在边缘处一次性解析,并在其下的每一层强制执行。

  1. 01

    控制平面

    一组服务负责租户的生命周期:注册、开通、套餐分配、配置、停用和注销。开通是一个幂等的工作流,中途失败可以重试,不会留下创建到一半的租户。控制平面是“有哪些租户、它们的资源位于何处”的唯一事实来源。

  2. 02

    租户解析与隔离层

    网关依据经过验证的令牌声明或域名识别租户,并将其作为请求上下文向下传递。在池化的 PostgreSQL 设计中,行级安全策略把每条查询绑定到该租户;在桥接和独立设计中,路由层选择租户对应的 schema、数据库或集群。缓存键、对象存储前缀和消息主题也按同样的方式限定范围。

  3. 03

    身份与访问

    认证委托给基于标准的身份提供方,它支持按租户配置的 SAML 与 OIDC SSO 连接、SCIM 账号同步和可配置的 MFA 策略。授权基于角色,角色限定在租户范围内,并在集中的策略组件中求值,使各服务的规则保持一致。平台人员对租户数据的访问单独管控、有时间限制并留有日志。

  4. 04

    计量与计费

    各服务把带有幂等键的用量事件发送到持久化的事件流。聚合流水线去重后,按租户和账期汇总,再把总量推送给负责开票、税务和收款的计费服务商。原始事件予以保留,任何一行账单都可以重新推算并解释清楚。

  5. 05

    权益与功能开关

    套餐以权益的形式表达:租户拥有哪些功能,适用哪些限额。各服务查询权益服务并配合本地缓存,而不是把套餐名称硬编码在代码里。功能开关是另一套独立机制,用于渐进式发布,因此发布代码与为某个客户启用某项能力是两个相互独立的决定。

  6. 06

    发布与迁移流水线

    部署采用滚动或蓝绿方式,配有自动健康检查和回滚。Schema 变更遵循扩展与收缩(expand and contract)模式,使新旧应用版本在发布期间可以运行在同一个数据库上。对于独立部署的租户,基础设施即代码和机群编排器(fleet orchestrator)分批应用变更,先从内部租户和低风险租户开始。

  7. 07

    按租户的可观测性

    日志、指标和追踪都携带租户标识,因此服务等级目标、错误率和成本可以按租户报告。配额和限流在网关以及连接池、队列等共享资源处执行。告警针对租户级别的劣化触发,而不只是针对全平台的平均值。

多租户 SaaS 架构
  1. 租户感知的边缘

    • 自定义域名
    • 租户解析
    • WAF
    • 按租户限流
  2. 身份与 SSO

    • SAML 与 OIDC
    • SCIM 账号开通
    • 角色与权限
    • MFA
  3. 控制平面

    只管理租户,从不承载其流量

    • 租户生命周期
    • 套餐与权益
    • 计费与计量
    • 功能开关
  4. 应用平面

    • 无状态服务
    • 后台任务
    • 租户上下文
    • Webhook
  5. 数据隔离

    按套餐层级选择隔离模型

    • 行级安全
    • 每租户独立 Schema
    • 专属数据库
    • 每租户独立密钥
  6. 按租户的可观测性

    • 用量指标
    • 带租户标签的链路
    • 吵闹邻居告警
    • 审计日志
控制平面管理租户、套餐与计费,应用平面为租户提供服务。租户身份在边缘解析,并贯穿每一层,直至数据存储和遥测数据。

一次合作交付什么

  • 租户模型决策记录,附成本与隔离分析
  • 支持租户自动开通与注销的控制平面
  • 涵盖 SSO、SCIM、MFA 与基于角色访问控制的身份集成
  • 用量计量流水线与计费服务商集成
  • 权益服务与功能开关框架
  • 零停机部署与 schema 迁移流水线
  • 按租户的仪表盘、配额与告警

开始之前

需要尽早做出的决策

池化、独立,还是桥接
当租户数量多且彼此相似时,默认采用在数据库层强制隔离的池化模型;它运行成本最低,发布也最简单。当客户要求专属基础设施、自有加密密钥或特定区域时,选择独立模型,并据此定价。桥接模型默认池化,同时可以把某个租户放到专属资源上,适合既面向小团队又面向大型企业销售的产品。
身份与计费:自建还是采购
除非它们就是您的产品,否则两者都应采购。托管的身份提供方和计费平台沉淀了多年在协议、税务和支付失败处理方面的边界情况。自建的应当是您特有的部分:租户模型、权益逻辑,以及向计费系统供数的计量流水线。
模块化单体,还是微服务
早期阶段的平台,通常更适合结构良好、模块边界清晰、单次部署的模块化单体。当某个模块有独特的扩展特征、发布节奏或归属团队时,再把它拆成服务。一开始就拆出许多服务,会在流量和人手都不足以支撑之前成倍增加运维工作。
何时提供单租户部署
当客户的要求无法通过逻辑隔离满足,并且合同金额足以覆盖运营成本时,才提供单租户部署。在此之前,先确保专属技术栈的开通与升级已经完全自动化。靠手工搭建单租户环境,SaaS 公司会在不知不觉中变成一家托管服务商。

常见问题

常见问题

现有的单租户产品能否改造成多租户?

通常可以,但工作量远不止加一个租户字段。它包括在整条请求路径上引入租户上下文、在数据层强制隔离、迁移现有客户的数据,以及改造后台任务、缓存和文件存储。我们一般分阶段进行,先建立隔离层和控制平面,再分批迁移租户。

如何证明租户隔离有效?

把它当作一项安全属性来测试。自动化测试会通过每一个 API 尝试跨租户读写,并在交付流水线中运行。数据库策略独立于应用代码进行评审和测试,隔离也被纳入渗透测试的范围。

零停机发布是否涵盖数据库变更?

可以涵盖,但需要纪律。变更被拆分为向后兼容的若干步骤:新增结构、双写、回填、切换读取,然后在后续版本中移除旧结构。会锁住大表的操作,使用在线迁移工具或分批执行。

你们基于哪家云构建?

设计不绑定某一家云厂商。我们使用主流公有云,并在托管服务能够减轻运维负担的地方选用托管服务。具体选择通常取决于您现有的云资源、数据驻留要求,以及未来负责运维该平台的团队所具备的技能。

有一套必须在生产环境中正常运行的系统?

告诉我们您正在构建什么。工程师会阅读您的留言,并在两个工作日内回复。