卷一讨论产品形状如何决定服务端形状,卷二讨论内容、社交与实时互动,卷三把交易、增长与平台化算清楚。到了卷四,问题换了一个问法:这套系统还能不能继续长大?
一次 3% 的切流
「回声」在第四个年头做了单元化改造。目标很明确:把用户按 ID 分到三个单元,任何一个单元故障,只影响三分之一用户,而不是全站。
改造分三期上线。第一期只把读流量切到新单元,写流量仍然走中心库;第二期双写;第三期切写。上线前演练过两次,回切也走过一遍,看起来没有问题。
第三期切写的那个凌晨,值班同学按手册把 3% 的用户路由到单元 B。十分钟后,客服群里开始出现「我的订单不见了」。排查发现,单元 B 的用户路由配置里,ID 区间写成了左闭右闭,而单元 A、C 是左闭右开。区间边界上的用户被同时路由到两个单元,读到的却是两份不同的数据。
这 3% 不是随机的 3%,而是每个区间边界上最活跃的一批用户。他们看到的订单列表时有时无,支付回调写到了另一个单元,库存对不上。
事故本身的修复只花了四十分钟:把区间改成统一的半开区间,清掉重复路由缓存。真正花时间的是后面两周:核对受影响的订单、补发消息、向用户解释、把「区间定义」写进所有单元的共享库,并为它加上属性测试。
这个事故说明了一件事:规模化不是把单机代码复制三份。每复制一份,就多一条边界;每条边界都可能有一处定义不一致,而定义不一致在低流量时几乎不会暴露。
规模化到底改变了什么
从单条链路到平台,至少有四条曲线同时变化。
| 曲线 | 单体阶段 | 规模化阶段 | 主要矛盾 |
|---|---|---|---|
| 流量 | 峰值可预测 | 突发、热点、跨地域 | 容量与调度 |
| 数据 | 单库可容纳 | 分片、冷热、迁移 | 一致性与成本 |
| 组织 | 一个团队 | 多团队、多地域 | 边界与决策 |
| 故障 | 局部重启 | 爆炸半径不可控 | 隔离与恢复 |
四条曲线不是独立变化的。流量涨十倍,数据就要分片;数据分片,跨片事务就消失;跨片事务消失,业务就要接受最终一致;最终一致需要补偿与对账,对账又需要组织上有人负责。任何一条曲线单独处理,都会在另一条曲线上留下债务。
所以本卷不按「技术组件」组织,而按「规模化过程中真实出现的决策」组织:什么时候拆、怎么隔离、容量怎么算、成本怎么管、稳定性怎么承诺、安全怎么守、平台怎么建、旧系统怎么迁、组织和决策怎么跟上。
三个不能省的判断
第一,先问「要不要」,再问「怎么做」。 拆分、单元化、分片、平台化,都是有代价的手段,不是成熟度标志。团队五个人、日订单五千,做单元化大概率是负收益。每一章都会先给触发条件,再给实现。
第二,每个方案都要有退出条件。 拆分要能回退,灰度要能回滚,平台要能下线,技术债要能还。只设计「怎么上」不设计「怎么退」,在规模化阶段是危险的,因为规模会把小错误放大成事故。
第三,数字要能解释。 「延迟降低了 30%」不是结论,除非说清分母、口径、测量条件。本卷的指标、容量、成本章节都会给出可复算的公式,示例数字标注为案例假设,真实跑过的输出才写「实测」。
为什么先讲拆分,后讲多活
第 1 章讲拆分,第 2 章讲多活,第 3 章讲突发流量。这个顺序不是按难度,而是按依赖。
没有清晰的域边界,单元化只是把一团耦合复制三份;没有单元化,多活就没有落点;没有多活与容量规划,大促只能靠堆机器。反过来,如果先做大促预案再做拆分,预案里会写满「扩容」「限流」,却无法回答「哪个单元可以独立降级」。
第 9、10、11 章用 Feed、IM、大促三个演进案例,把前面的决策串起来。它们不是新技术,而是「同一套系统在不同阶段的改造记录」。
与前三卷的关系
- 卷一给出产品约束、账号、BFF、入口、缓存、异步、发布与观测的基础;本卷默认这些能力已经存在。
- 卷二给出内容、Feed、社交、IM 的模型;本卷的第 9、10 章直接在这些模型上做演进。
- 卷三给出交易、库存、支付、券、活动与增长;本卷的第 11 章大促会反复引用它们。
- 本卷不重复前三卷的定义,只讨论「当规模变化时,这些定义哪里会失效」。
如果你是从本卷开始读,建议至少先看卷一第 1 章、卷二第 3 章、卷三第 1 章,知道「回声」的基本形状。
一个反例:把平台当成目标
有一段时间,「回声」内部把「服务化率」当成架构健康的核心指标。半年后,服务数量从 12 个涨到 87 个,服务化率很好看,但发布一次要跨 9 个团队,故障定位要翻 6 个系统,机器成本涨了 40%。
问题不在服务化本身,而在于把手段当成了目标。服务化的目的是让边界清晰、让团队能独立演进,不是让服务数量变多。当服务数量增加没有带来发布独立性,反而增加了协调成本时,这个指标就失效了。
本卷第 8 章与第 12 章会分别从平台与组织两个角度讨论这个问题。判断标准始终是:这次变化让哪个团队、哪条链路、哪个指标变好了?如果说不清,就先别做。
本卷的 13 章
- 单体到服务化:拆分的触发条件、按域拆还是按层拆、回退方案。
- 多活与容灾:单元化与用户路由、数据同步与冲突、切换回切与演练。
- 突发流量:热点特征、弹性扩容与预热、降级与排队。
- 数据规模:分库分表与路由、冷热分离与归档、迁移与双读。
- 成本治理:单位经济模型、存储与带宽成本、闲置回收与预算。
- 稳定性体系:SLO 与错误预算、故障分级与应急、复盘与改进闭环。
- 安全与合规:反爬与防刷、内容安全与未成年人保护、个人信息与审计。
- 研发效能:环境制品与流水线、内部平台边界、平台采纳与反悔成本。
- 演进案例 Feed:旧链路基线、双写灰度切换、结果与回退条件。
- 演进案例 IM:会话归属与路由、消息同步与顺序、切换演练与用户无感。
- 演进案例大促:容量规划与压测、限流降级预案、大促复盘。
- 决策与组织:团队边界与系统边界、决策权与评审、技术债与演进路线。
- 全书收口:从 MVP 到规模化的路线图、架构健康度自评、结语。
第 1–8 章是能力,第 9–11 章是案例,第 12–13 章是决策与收口。能力章回答「怎么做」,案例章回答「做的时候会发生什么」,决策章回答「谁来做、什么时候做、什么时候停」。
规模从哪里来
「回声」的规模不是一天涨起来的。下面这张表是四个阶段的案例假设,用来说明每一阶段的主要矛盾,不代表任何真实业务数据。
| 阶段 | 日活 | 日订单 | 团队数 | 主要矛盾 |
|---|---|---|---|---|
| 单机 | 1 万 | 2 千 | 3 | 功能能不能上线 |
| 服务化 | 30 万 | 6 万 | 9 | 发布互相阻塞 |
| 多单元 | 200 万 | 40 万 | 20 | 故障爆炸半径 |
| 平台化 | 800 万 | 150 万 | 45 | 成本、边界与决策 |
从 1 万到 800 万,日活涨了 800 倍,但团队数只涨了 15 倍。这意味着人均承载的用户变多,也意味着任何一个团队的失误,影响面都更大。架构要解决的不是「人多」,而是「人多了之后,边界还能不能守住」。
另一个常被忽略的数字是变更频率。单机阶段一周发布一次,服务化之后一天几十次,平台化之后一天几百次。发布频率上升,回滚能力就必须同步上升;否则每次发布都变成一次赌博。
一次容量评审
大促前两周,容量评审会上有两组数字。业务方说峰值会到平时流量的 8 倍;运维方说按过去三次大促,实际峰值只有 4.5 倍。两边都有依据,争了半小时。
最后决定按 6 倍准备,并留 30% 余量。会后有人问:如果真到 8 倍怎么办?答案不是「继续加机器」,而是三条预案:非核心接口降级、下单排队、超出容量后拒绝并给出明确提示。
这次评审留下的经验有三条:
- 容量规划不是算一个数,而是算一个区间加一套预案。
- 业务峰值与历史峰值都有偏差,取中间值并写明依据,比争论谁对更有用。
- 余量不是越多越好,余量意味着成本;关键是知道余量用完时先牺牲什么。
第 3 章与第 11 章会把这三条展开成可执行的步骤。
单元化的三个前置条件
那次 3% 的切流事故之后,「回声」给单元化补了三个前置条件,任何新单元上线前必须满足:
- 路由规则有单一实现。 所有服务引用同一个路由库,区间定义、哈希算法、边界处理只有一份代码,且有属性测试覆盖。
- 数据归属可判定。 每条数据能回答「属于哪个单元」,跨单元访问有明确路径,不允许「先查一下再说」。
- 切换与回切都演练过。 不只是切过去,还要在不通知业务方的情况下切回来,验证数据没有丢、没有重。
这三条看起来朴素,却挡住了后来两次扩容中的问题。第 2 章会把它们展开成路由、同步、演练三节。
一个日志字段的成本
平台化第一年,成本涨得最快的一项不是数据库,也不是带宽,而是日志。
原因很普通:为了方便排查,每个服务都把完整请求体打进日志,包括用户地址、商品快照、优惠明细。单条日志从 2 KB 涨到 11 KB,日志量随流量线性上涨,存储成本一年翻了四倍。
更麻烦的是合规问题:请求体里有手机号和地址,日志平台没有脱敏,保留期设的是 180 天。一次内部审计发现后,团队花了三周做字段清理与历史数据删除。
这件事的教训不是「日志要少打」,而是:规模化之后,任何一个「顺手加上去」的字段,都会乘以流量、乘以保留期、乘以副本数。第 5 章与第 7 章会分别从成本与合规两个角度讲同一件事。
三种读法
按能力读。 第 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 章。回答「规模化需要哪些能力,各自的触发条件与退出条件是什么」。适合正在做架构升级的团队。
按案例读。 第 9 → 10 → 11 章,再回看第 1、2、3 章。回答「一次真实演进会踩哪些坑」。适合已经决定要改、需要具体方案的人。
按决策读。 第 12 → 13 章,再回看各章的「触发条件」。回答「谁来决定、什么时候做、什么时候停」。适合技术负责人与架构评审者。
三种读法都不要求从头读到尾,但建议至少完整读第 1 章与第 13 章:前者定义「该不该开始」,后者定义「怎么判断做完了」。
数字口径
本卷的数字分三类,读的时候请区分:
- 案例假设值:日活、订单、成本、QPS 等,用来表达比例关系,不是实测。
- 代码实测值:Go 测试与本机运行的输出,会附命令与结果,耗时可写「随机器变化」。
- 阈值建议值:SLO 目标、扩容系数、降级水位等,是起点,需要按自己的业务重新标定。
任何标注「实测」的内容,都可以在实验工程里用同一命令复现;没有标注的,请当作示例。规模化讨论里最危险的数字是「友商做到了」——别人的分母、窗口与口径,通常和你不一样。
为什么案例选 Feed、IM 与大促
三个案例分别代表三种不同的演进压力。
Feed 代表读放大。一次发布要扇出到几百个关注者,读流量远大于写流量;改造成本主要在读路径的缓存、排序与降级。
IM 代表状态归属。会话、消息、已读状态都要落在某个节点上,节点迁移意味着状态迁移;改造成本主要在一性、顺序与补洞。
大促 代表瞬时峰值。流量在几分钟内涨到平时的数倍,之后迅速回落;改造成本主要在容量、限流与预案,而不是长期架构。
这三种压力对应第 2、3、4 章的能力:隔离、弹性、数据规模。案例章不是重复讲能力,而是展示能力组合起来之后的真实取舍。例如 Feed 改造既要用到单元化(读流量就近),又要用到降级(排序服务不可用时退回时间序),还要用到成本(缓存命中率与机器数)。
一次回切演练
单元化上线三个月后,团队做了一次没有提前通知业务的回切演练:把单元 B 的 10% 用户切回中心,观察 30 分钟,再切回去。
演练暴露了三个问题:
- 切回中心后,部分用户的未读计数没有同步,数字比实际少。
- 回切时缓存没有预热,前两分钟数据库 QPS 涨了 3 倍。
- 有一个后台任务只认单元 B 的库,切回后任务失败但没有告警。
这三个问题在「只切不回」的演练里都不会出现。回切不是切换的逆操作,它有自己的数据路径、缓存状态与任务依赖。第 2.3 节会把回切单独作为一节,而不是附在切换步骤后面。
演练的另一个价值是暴露「谁知道怎么回」。那次演练中,值班同学按手册操作到第三步就卡住了,因为手册里写的配置项在半年前改过名字。手册与系统一起演进,是规模化阶段容易被忽略的维护工作。
架构演进的三条底线
不管采用哪种方案,本卷反复强调三条底线。
第一条:任何变更都要能回退。 回退不等于「再发一版」,而是有明确的数据兼容窗口、开关与操作步骤。拆分、迁移、平台切换都一样。
第二条:任何边界都要有单一实现。 路由规则、权限判断、金额计算、状态迁移,同一件事只能有一份代码或一份配置。多处实现早晚会分叉,而分叉在低流量时不痛,在高流量时致命。
第三条:任何指标都要有分母与负责人。 SLO、成本、容量、健康度,没有分母的指标无法比较,没有负责人的指标不会有人维护。第 6 章与第 12 章会分别从稳定性与组织角度讲这一条。
这三条不新鲜,但在规模化阶段最容易被「先上线再说」挤掉。本卷的每一章,都会在结尾回到这三条,检查方案是否满足。
四个里程碑
如果把规模化拆成可验收的里程碑,大致是下面四步。每一步都有明确的「完成标志」,也有明确的「不要提前做」的理由。
| 里程碑 | 完成标志 | 不要提前做的原因 |
|---|---|---|
| 模块化 | 包边界清晰,依赖测试通过 | 边界没定就拆分,只是把耦合搬远 |
| 服务化 | 核心域可独立发布、独立回滚 | 发布不独立,拆分只增加协调成本 |
| 单元化 | 单单元故障不影响全局,回切演练通过 | 路由与数据归属没统一,切流就是事故 |
| 平台化 | 多业务共用能力,有 SLA 与退出机制 | 使用率不足时,平台会变成第二个维护负担 |
四个里程碑不是必须依次完成,但跳步通常要付两次成本。例如没做模块化直接拆服务,边界会在服务之间重新长出来;没做单元化直接多活,故障会跨地域扩散。
里程碑的验收不是「上线了」,而是「演练过、有数据、有人负责」。第 13.1 节会把这张表展开成路线图,并给出每个阶段的退出条件。
一个练习
在开始读第 1 章之前,花二十分钟做一个小练习:找出你所在系统的三条边界,并写下它们的定义位置。
- 数据边界:哪张表、哪个库只属于一个服务?有没有两个服务同时写同一张表?
- 发布边界:哪个服务可以独立发布而不影响别人?发布失败时,回滚需要几个团队配合?
- 故障边界:哪个组件挂掉只影响一部分用户?这个「一部分」是怎么划出来的?
每条边界都写三行:定义在哪份代码或配置里、谁负责维护、最近一次验证是什么时候。如果某条边界写不出「定义位置」,它大概率只存在于口头约定里;如果写不出「最近验证」,它可能已经和现状不一致。
这个练习没有标准答案,但它能帮你判断本卷哪几章与你最相关。数据边界写不清,先读第 4 章;发布边界写不清,先读第 1、8 章;故障边界写不清,先读第 2、6 章。
本卷不回答什么
- 不写具体云厂商的产品选型与报价。成本章节给的是计算方法,不是采购建议。
- 不写 Kubernetes、服务网格的部署细节。这些属于运维手册,不属于架构判断。
- 不写完整的安全攻防。只写与业务架构相关的边界与检查项。
- 不写组织管理的完整理论。只写与系统边界直接相关的团队边界与决策权。
- 不承诺「按本卷做完就能支撑十倍流量」。规模化的前提是业务、团队、资金同时到位,架构只是其中一项。
读完能做到什么
- 拿到一个「要不要拆」的问题,能列出触发信号与反例,而不是直接给方案。
- 设计单元化时,能说清路由规则、数据归属、切换与回切条件。
- 做容量规划时,能从业务峰值推到实例数,并标注安全系数。
- 看一份 SLO 或成本报表时,能问出分母、窗口与口径。
- 面对旧系统迁移,能写出双写、比对、灰度、回退四步,而不是「重写一遍」。
- 在架构评审会上,能区分「可逆决策」与「不可逆决策」,并给出对应的评审级别。
一个提醒
规模化阶段最危险的不是技术难题,而是「看起来已经解决」。服务拆了、单元切了、监控有了、复盘写了,但边界定义不一致、回退没演练、指标没口径、责任没归属。这些问题平时不响,出事时一起响。
读本卷时,建议每读完一章,回到自己的系统问三个问题:这条边界定义在哪?这个方案怎么退?这个数字谁负责?三个问题都有明确答案,才算真正落地。
如果答案模糊,通常有三种表现:
- 边界「大家都知道」,但没人能指出那份唯一的配置或代码。
- 回退方案「早就想好了」,但从来没在预发或生产演练过。
- 指标「一直有人看」,但问分母和窗口时,三个人给三个答案。
- 方案「上线了」,但没人说得清它解决了哪个具体问题、下一步该验证什么。
出现任何一种,说明这一章的内容还没有真正进入系统,只是进入了文档。文档不是坏事,但规模化阶段,文档与实现的距离会被流量放大。
下一章从「什么时候该拆」开始。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。