Skip to content
架构中级阅读约 1 分钟

架构实战 · 微服务与 SaaS 多租户平台 ​

本篇定位

讲清一套中型 SaaS 产品的微服务底座:服务怎么拆、注册配置、网关、链路追踪、可观测,以及 SaaS 的命门——租户隔离、资源争抢、租户级配额。方法见 架构方法论、容量估算、高可用蓝图,容器编排见 K8s 架构。

一、业务特点与规模估算 ​

典型场景:一套面向中小企业的协同办公/CRM SaaS,2000 家付费租户,每家 10~500 个账号。多租户意味着一个大共享池,但必须按租户隔离数据与资源。

指标假设值说明
付费租户数2000 家头部 50 家占 60% 流量
注册企业用户5 万累计账号
日活10 万工作日 9~18 点高峰
峰值 QPS3000上班打卡/集中登录
在线用户8 万长连接
微服务数量30 个用户/权限/组织/业务/文件/通知等
数据量500 GB 业务库多租户共享库,按 tenant_id 隔离
带宽峰值300 Mbps文件上传下载

核心结论:复杂度不在并发,而在拆分治理 + 多租户隔离 + 可观测——一个头部租户跑批任务不能把全平台拖死。

1.1 容量推算自洽 ​

推算项计算结果
平均 QPS日活 10 万 × 人均 15 请求 ÷ 86400≈ 17 QPS
峰值 QPS平均 × 180 倍(上班 2 小时集中)≈ 3000 QPS
Worker 需求30 服务 × 每服务 2 实例 × 0.5 核8 台 16C Worker 跑满后 HPA 扩
单租户峰值头部租户 500 账号同时在线 ≈ 200 QPS占总量 7%,但必须隔离
数据库500GB,年增 200GB1T ESSD,按 tenant_id 建联合索引

3000 QPS 对 K8s 集群毫无压力,真正要防的是「头部租户单租户打爆共享池」。

二、总体架构图 ​

分层:接入层(CDN+网关)→ 应用服务(K8s 上的 30 个微服务)→ 注册配置(Nacos)→ 缓存/消息/数据库/对象存储 → 可观测(监控/日志/链路追踪三位一体)。

三、服务器清单 ​

角色数量CPU(核)内存数据盘带宽软件 / 职责
K8s Master3816GESSD 200G内网K8s 1.30 控制面;见 K8s 架构
K8s Worker81664GESSD 500G内网跑 30 个微服务 Pod
API 网关3816GESSD 100G100MbpsAPISIX 集群
Nacos 注册配置3816GESSD 200G内网注册 + 配置中心集群
MySQL 主从2主2从1664GESSD PL2 1T内网多租户共享库;见 MySQL
Redis3主3从832GESSD 200G内网缓存/会话;见 Redis
Kafka3816GESSD 500G内网通知/事件;见 Kafka
Elasticsearch31632GESSD 1T内网日志/全文检索
OSS云---按量租户文件
监控栈2832GESSD 1T50MbpsPrometheus/Grafana;见 SLO
链路追踪1816GESSD 500G内网Jaeger/Tempo

合计自建约 30 台。与规模自洽:8 台 Worker 跑 30 个低峰常驻微服务,K8s HPA 按 CPU 自动扩缩容应对上班高峰。

四、服务依赖与各自解决的问题 ​

服务解决什么问题与谁交互同步/异步
API 网关统一入口、JWT 鉴权、路由转发、按租户限流所有微服务同步
注册配置中心服务发现、动态配置(开关/限流参数)不下线发布所有微服务长连订阅
用户权限服务登录、RBAC、token 校验MySQL、Redis同步
业务核心服务主业务逻辑MySQL、Redis、其他服务同步 RPC + 异步事件
文件服务上传下载直传 OSSOSS、CDN同步签名
通知服务站内信/邮件/企微Kafka、外部通道异步
MySQL业务数据持久化(带 tenant_id)各服务同步读写,主从异步复制
Redis会话、租户级缓存各服务同步
可观测三件套指标/日志/链路定位慢调用与故障全链路异步采集

五、关键设计点与坑 / 注意事项 ​

  1. 租户隔离模型:本方案用共享库 + tenant_id 行级隔离(成本最优)。必须在所有 SQL 强制带 tenant_id,推荐用 MyBatis 拦截器自动拼接,杜绝跨租户数据泄露。头部大客户可后续迁独立库。
  2. 资源争抢( noisy neighbor):某租户跑批量导入/报表,会吃光 Worker CPU 和数据库连接。做法:租户级并发限流 + 配额(QPS/存储/API 调用量),重任务隔离到独立线程池/K8s namespace,大租户单独节点池。
  3. 租户级配额:按套餐限制账号数、存储容量、API 调用次数;网关层按 tenant_id 做令牌桶限流。
  4. 服务拆分粒度:不要一上来拆 30 个,先按业务域拆,避免分布式事务满天飞。跨服务调用尽量异步事件。
  5. 配置与开关:Nacos 管动态配置(灰度开关、限流阈值),改配置不发版;但配置变更要审计 + 回滚。
  6. 链路追踪:一个请求跨 5 个服务出问题,没有 traceId 根本查不动。全链路透传 traceId,慢调用可视化。
  7. 多租户备份与恢复:备份要能按租户恢复,不能整库回滚影响所有客户。

5.1 三种多租户隔离模型对比 ​

模型数据隔离成本适用
独立库(一租户一库)最强最高头部大客户/合规要求高
共享库 + tenant_id 行级中(靠代码)最低本方案,中小租户
共享库 + 独立 Schema中中折中,迁移麻烦

本方案先用共享库跑量,给头部大客户预留「迁独立库」的扩展点:业务表主键都带 tenant_id,迁移时按租户导库即可。

5.2 租户限流示意(网关层) ​

text
请求进入网关 → 解析 JWT 取 tenant_id
→ 查该租户套餐配额(Redis)
→ 令牌桶:超限直接返回 429 + 友好提示
→ 转发到对应服务

六、安全与高可用 ​

  • 边界防护:网关 WAF + 按租户限流;管理后台独立域名 + 堡垒机。
  • 鉴权授权:JWT 网关统一校验;数据级 RBAC,所有查询强制 tenant_id。
  • 数据加密:HTTPS;租户敏感字段加密;OSS 按租户前缀隔离 + 签名 URL。
  • 消除单点:K8s 多副本反亲和;Nacos 3 节点;MySQL 主从;Redis Cluster;Kafka 3 副本。
  • 熔断降级:某下游服务挂,网关/熔断组件返回降级,不拖垮整个调用链。
  • 多可用区:Worker 跨可用区调度,MySQL 半同步。

6.1 关键监控指标 ​

指标告警阈值说明
接口 P99 RT> 500ms跨服务慢调用,用 traceId 定位下游
按租户 QPS单租户 > 配额 80%触发限流预警
K8s Pod 重启次数> 3 次/10 分钟CrashLoop,回滚
MySQL 连接数> 最大连接 80%连接池泄露或扩容
Nacos 服务列表实例数异常服务上下线异常
跨租户访问拦截出现即告警可能数据泄露,紧急排查

七、上线后可能出现的状况与应对 ​

类别征兆处置
性能类某接口跨服务 RT 高用链路追踪定位是哪个下游慢,加缓存/优化慢 SQL
性能类某租户整体慢noisy neighbor,查该租户是否在跑批,限流/隔离
容量类K8s Worker CPU 长期高HPA 未生效→查指标;扩容 Worker 节点
容量类MySQL 连接数打满连接池配置过大/泄露,定位泄露服务,扩库或加中间件
故障类Nacos 挂服务间已有本地缓存路由,短时可用;尽快恢复集群
故障类网关挂多副本自动切换;检查证书/配置错误导致全部 502
故障类某微服务 Pod CrashLoop看日志/就绪探针,回滚版本,流量切走
故障类MySQL 主挂提升从库,确认 tenant_id 数据无丢失
故障类Redis 挂缓存失效直查库,限流保护,按租户限流防雪崩
大促/活动大租户全员集中登录网关按租户限流,登录服务扩副本,验证码降刷
扩容新租户激增K8s HPA 自动扩业务服务;数据库评估再分库
数据类跨租户数据泄露投诉紧急排查拦截器是否漏加 tenant_id,紧急修 + 审计日志
数据类慢 SQL 拖库开启慢查询日志,热点报表迁 ES/只读从库
数据类主从延迟延迟敏感读回主库,大租户批量任务错峰
性能类某租户批量导入导致全平台卡顿触发租户级并发上限,重任务隔离到独立线程池
故障类ES 日志集群磁盘满日志保留策略缩短,冷日志转 OSS,停掉非关键 debug 日志
故障类配置中心发错配置Nacos 配置一键回滚历史版本,灰度先小流量验证
容量类OSS 某租户存储超套餐配额告警,通知租户清理,超限后只读禁止上传
数据类某租户数据误删按租户从备份恢复(不影响其他租户),先恢复到临时库再核对
故障类某微服务雪崩拖垮上游熔断该服务,上游返回降级数据,快速定位根因服务
性能类通知服务发邮件慢拖垮通知全异步 Kafka,不阻塞主链路,慢只影响通知时效
故障类Redis Cluster 大 key 阻塞拆分大 key,热 key 本地缓存,避免单 key 打满单线程
容量类新签大客户需独立库按预留扩展点把该租户数据迁独立库,网关路由到新库
故障类日志爆量打满 ES降级采样、缩短保留期,关闭无谓的访问日志
性能类报表接口慢报表走只读从库或预聚合,不在线查明细
容量类通知邮件/短信超套餐按租户配额限流,营销通知合并发送
故障类配置推送导致全量 500Nacos 回滚到上一版本,灰度配置先在小流量验证
性能类跨服务 RPC 串行调用慢改并行调用或异步事件,缩短调用链
容量类某租户文件数暴涨配额告警,临时冻结该租户上传,引导清理
故障类长连接/推送延迟查 Kafka 积压,推送 Worker 扩容,按通道分级限流
性能类首次登录慢预热用户权限缓存,JWT 校验本地化,减少 RPC
故障类某 Worker 反复重启看日志 OOM/配置错误,回滚镜像版本,隔离坏节点

7.1 演进路线 ​

租户数破 5000、单库压力上来后:共享库按租户维度水平分库;头部大客户迁独立库;引入服务网格做细粒度熔断;可观测从 Prometheus 扩展到全链路 profiling。先把隔离与配额做扎实,再谈拆分。


相关阅读:架构方法论 · 容量估算 · 高可用蓝图 · K8s 架构 · MySQL · Redis · Kafka · SLO