本技术文章面向正在设计SaaS产品或对已超出初始设计的产品进行重构的CTO、架构师及高级工程师。我们的SaaS平台工程指南介绍了孤岛模式、池化模式和桥接租户模型及控制平面;本文在此基础上深入探讨各层隔离的实施方式、数据分区方法、计费接入方式、AI功能如何在租户边界内运行以及平台如何扩展。市场平台内容请参阅市场平台架构。
背景:租户、用户与部署
首先需要明确租户的定义。在B2B SaaS中,租户通常是一个拥有多名用户的客户组织;部分客户可能需要多个租户,例如独立的子公司,或独立的测试与生产环境。在B2C产品中,一个租户可能是一个人、一个家庭或一个群体。微软Azure架构中心指出,这一定义以及租户模型是否被客户接受,既是商业决策,也是技术决策。
需要将逻辑租户与为其提供服务的部署分开。部署(有时称为stamp)是一套基础设施。多个租户可以共享一个部署,也可以一个租户独享一个部署。从一开始就维护一份租户到部署的映射表,日后可以在不重写应用程序的情况下将租户迁移至不同部署。
隔离按层决定
AWS关于SaaS租户隔离策略的白皮书将隔离称为SaaS设计的基础,并将跨越租户边界描述为可能对业务造成不可挽回的事件。微软将隔离描述为一个连续体,而非单一开关。实践中,每一层各有其答案:
| 层 | 共享选项 | 隔离选项 | 决定因素 |
|---|---|---|---|
| 计算 | 共享应用服务器 | 每租户独占服务器或容器 | 性能保障、噪声邻居、客户要求 |
| 数据库 | 共享表并附加租户键 | 每租户独立schema或数据库 | 数据敏感性、备份与恢复需求、规模 |
| 文件存储 | 共享存储桶并使用租户前缀 | 每租户独立存储桶或容器 | 访问策略、数据驻留、保留规则 |
| 缓存 | 共享缓存并使用租户前缀键 | 每租户独立缓存 | 键冲突风险、内存压力 |
| 队列与任务 | 共享队列并为任务添加租户标签 | 每租户或每层级独立队列 | 公平性,防止某一租户的积压延误其他租户 |
| 搜索索引 | 共享索引并按租户过滤 | 每租户独立索引 | 索引大小、每租户相关性调优 |
| 日志与指标 | 共享管道并按租户标记 | 受监管租户使用独立数据流 | 支持需求、审计要求 |
| 加密密钥 | 平台托管密钥 | 每租户独立密钥 | 合同要求、下线处理(销毁租户密钥) |
| AI检索索引 | 共享向量索引并强制执行租户过滤 | 每租户独立索引或命名空间 | 数据敏感性、索引大小、下线处理 |
一种常见且合理的结果是:应用层池化,而需要隔离的租户则独立存储数据。微软将部分组件按租户拆分、其余共享的方式称为水平分区;为选定租户提供完整独立部署的方式称为垂直分区。
数据分区选项
| 模式 | 隔离实施方式 | 优势 | 权衡 | 适用场景 |
|---|---|---|---|---|
| 共享schema,每行附加租户键 | 每条查询包含租户过滤,并由数据库行级策略支撑 | 成本最低、运维最简单、跨租户报表容易 | 若缺少数据库策略,遗漏过滤可能导致数据泄露;存在噪声邻居问题 | 大量小租户 |
| 每租户独立schema | 同一数据库中每租户使用独立schema | 分隔清晰,单租户恢复更简便 | 迁移需在每个schema上运行一次;schema数量存在实际上限 | 数十至数百个中型租户 |
| 每租户独立数据库 | 每租户使用独立数据库 | 强隔离、可按租户调优、支持数据驻留选项 | 成本较高,需对迁移和备份进行集群管理 | 大型或受监管租户 |
| 每租户独立部署 | 每租户独立技术栈 | 最强隔离、独立发布时间 | 成本最高;需运维大量部署 | 少量超大型或受监管客户 |
对于池化数据库,需在数据库层本身而非仅在应用代码层强制执行隔离。PostgreSQL的行安全策略是一种方式:在表上启用后,除非策略允许,否则行将被隐藏,因此不带租户过滤的查询返回空结果而非所有数据。有两点细节需要注意。策略须在每张表上单独启用;表所有者、超级用户及具有BYPASSRLS属性的角色默认绕过策略。因此应用程序应使用不拥有这些表的角色连接,或者对表强制启用行安全,以使策略同样对表所有者生效。
请求流程与租户上下文
多租户平台中的请求应始终遵循相同路径:
-
解析租户
,来源为子域名、自定义域名或认证令牌中的声明,绝不从客户端可自由修改的值中获取。
-
对用户进行认证
,并确认该用户属于该租户。
-
使用租户映射表将租户映射至其部署和数据位置
。
-
为数据库会话设置租户上下文
,使行级策略或schema选择自动生效。
-
将上下文传播
至后台任务、事件、缓存键、日志、指标及AI检索调用。
-
结合租户及用户在该租户中的角色进行授权检查
。
大多数租户数据泄露源于某一步骤在某处被跳过:缺少上下文的后台任务、缺少租户前缀的缓存键,或信任请求中租户ID的管理端点。
计费与计量架构
多租户SaaS中的计费是一条流水线,而非单一集成。
| 阶段 | 组件 | 设计说明 |
|---|---|---|
| 用量事件 | 应用按租户和功能发出事件 | 从首次发布起即开始发出,即便当前采用固定定价 |
| 计量 | 将事件聚合为每租户每周期的用量 | 幂等性:重试事件不得被重复计费 |
| 权益 | 决定每个租户可使用的功能及上限 | 代码检查权益,而非套餐名称 |
| 定价计算 | 将价格应用于用量和套餐 | 通过配置实现,定价变更无需发布 |
| 开票与付款 | 计费或支付服务商进行收费和开票 | 卡片数据保留在服务商处 |
| 收入报表 | 收入、流失和付款失败的财务视图 | 基于与计量相同的数据构建 |
| AI用量 | 每租户每功能的模型调用次数和token数 | 受权益限制,防止单一租户消耗套餐利润空间 |
-
按租户固定订阅
需要权益和计费生命周期管理;计量对了解每租户成本仍有价值
-
按席位
需要可靠的每租户用户数统计及周期中变更规则
-
按用量计费
需要精准的幂等计量及向客户展示用量
-
混合(基础费用加用量)
需要以上所有内容,加上清晰的限额和超额规则
AI功能:数据隔离与每租户模型成本
助手、AI搜索和摘要功能在一次请求中读取的租户数据量远超大多数页面,因此需要在相同位置强制执行相同边界。AI治理为其制定策略。
- 在提示词之外过滤检索。检索服务从会话上下文中应用租户和用户权限。提示词中只使用该客户数据的指令并非隔离手段。
- 所有AI缓存均以租户为键。未添加租户键的缓存答案和嵌入向量可能将一个客户的内容返回给另一个客户。
- 避免将租户数据用于共享训练。不要用单一租户的数据微调共享模型,并选择条款中排除以请求数据进行训练的模型服务商。受监管租户可能需要专属区域或专属模型部署。
- 按租户计量模型成本。不同租户的token和调用量差异悬殊;按功能归因并通过权益强制限额。
- 下线时删除数据。离开的租户的嵌入向量、索引和已记录的提示词随其数据库行一同删除。
扩展选择
| 选择 | 适用时机 | 成本与复杂度 |
|---|---|---|
| 纵向和横向扩展共享部署 | 早期增长且租户类型相似 | 最低;注意共享资源上限 |
| 将租户分片至多个数据库 | 单一数据库接近上限 | 中等;需要租户映射表和跨分片报表 |
| 新增部署stamp | 区域或租户数量增长超出单一技术栈 | 较高;需要自动化部署和发布 |
| 将大型租户迁移至专属资源 | 某一租户占据主导负载或需要隔离 | 按租户;需要经过测试的迁移路径 |
| 噪声邻居控制 | 始终 | 低;速率限制、每租户配额和公平任务调度 |
提前规划租户迁移路径:租户数据如何从共享数据库迁移至其专属数据库、流量如何切换,以及如何验证结果。提前设计比临时应对容易得多。
运营:发布、迁移与恢复
- 分环发布。先向内部租户推出,再覆盖一小部分客户,最后全量发布,并使用每租户功能开关。
- 自动化全集群schema迁移。在每租户schema或每租户数据库模式下,一次发布意味着大量迁移;需追踪每个租户所处的版本。
- 支持单租户恢复,而非仅限整个平台。客户会要求恢复单个租户的数据;在他们提出之前先进行测试。
- 计量每租户成本。将计量数据与云账单结合,了解哪些租户和套餐能够覆盖其成本。
测试证据:测试内容
以下为通用工程实践,并非特定项目的成果:
- 跨租户访问测试。对每个端点和任务进行自动化测试,尝试读取或修改其他租户的数据,测试必须失败。
- 行策略测试。在没有租户上下文的情况下运行查询必须返回零行,包括在应用程序的数据库角色下。
- 噪声邻居负载测试。一个租户产生高负载,同时测量其他租户的响应时间。
- 单租户恢复测试。将一个租户从备份恢复到干净环境并比对记录。
- 计量测试。重放和重复的事件必须产生相同的用量总计。
- 跨租户AI测试。询问助手关于另一租户记录的问题必须找不到任何内容,包括通过缓存答案。
更广泛的检查项请参阅我们的SaaS安全清单。
案例:Printcart
Printcart是Netbase五大业务部门之一,是一个Web to Print及按需印刷平台,将在线订单转化为印刷就绪文件并路由至履约环节。它可在商家自有店铺上运行,也可作为Shopify、Wix和WooCommerce应用,安装周期约7天,目前服务2000+家店铺。以一个产品服务如此多的商家,正是本文所描述的多租户问题:每位商家需要在共享平台上拥有各自的目录、订单和店铺连接。Printcart案例记录介绍了Netbase JSC的工程与运营内容,印刷与包装展示了行业背景。
在自有产品之外,Netbase JSC自2020年起作为离岸开发与管理合作伙伴,参与为一家未具名美国客户构建多租户云ERP SaaS平台,面向中小型企业以SaaS形式销售。
Netbase JSC的多租户构建方式
Netbase JSC与AWS、Google Cloud、DigitalOcean和Cloudflare合作,不声称任何云合作伙伴级别或云认证。典型周期为SaaS MVP 8至12周、中级产品3至6个月、企业平台6至12个月或更长,具体取决于范围;以上均为范围估算,非报价。安全性从第一个迭代开始内嵌设计:安全代码审查、传输层TLS加密、静态AES加密、基于角色的访问控制、管理后台MFA、漏洞扫描及灾难恢复规划。AI模型按产品选择,不绑定单一供应商。SaaS开发服务负责构建产品,SaaS产品加速器从账户、租户、角色和计费的可复用模块出发。
本文的局限性
- 本文描述的是通用模式和一般实践;正确的组合取决于您的租户、数据、地区及客户合同。
- 所引用的AWS白皮书已被AWS标注为历史参考资料;其隔离原则仍被广泛采用,但服务具体细节请参阅AWS当前指南。
- PostgreSQL作为数据库层隔离的一个示例;其他数据库提供不同的机制。
- 周期为典型范围。Printcart的描述来自其已发布的产品信息;本文不对其声称任何性能指标。
下一步
请分享您的租户概况、数据敏感性和定价模型,我们将预约解决方案评审,为您的首次发布选择隔离和计费设计。您也可以查看相关服务或浏览更多Netbase洞察。
相关服务与解决方案
AI就绪SaaS开发——来自自营SaaS平台的团队
Netbase JSC为创始人和产品团队提供SaaS开发服务,助力多租户订阅软件的上线与规模化扩展,涵盖客户愿意付费的AI功能。我们自主构建并运营SaaS平台Printcart及AI驱动的Cloodo工作空间,并将这一经验带入客户项目。典型SaaS MVP周期为8至12周,具体取决于范围、集成及评审速度。
Learn More
SaaS产品加速器:基于Netbase成熟模块,快速构建AI就绪的SaaS产品
SaaS产品加速器是Netbase提供的一套可复用模块,涵盖账户、计费、权限与集成,帮助创始人和产品团队更快推出订阅制软件,并从首个版本起支持产品内AI功能。模块复用最多可缩短60%的开发时间,该方案已在Netbase自有的网络印刷SaaS产品Printcart上得到验证。
Learn More
与 Netbase 远程合作
Netbase 所有项目均远程交付,任何国家、任何行业的客户均可与我们合作;Netbase 已服务全球 80 个国家的客户。合同与发票由 Netbase JSC 开具,款项通过银行转账至 Netbase JSC 公司账户或 PayPal Business 支付。欢迎通过 WhatsApp 或邮件联系 CEO Huy Nguyen(David)。
讨论项目
Netbase JSC 帮助企业设计、构建、现代化和运营数字产品及 AI 驱动的业务系统。project@netbasejsc.com
+84 937 869 689
91 Nguyen Chi Thanh, Dong Da, Hanoi, Vietnam
取得联系
告诉我们您想构建、现代化或运营什么。