专业书籍精读 · SRE · 合辑 01
Site Reliability Engineering · Ch 11 / 13 / 14 / 16 · Google · 2016
你刷的每个 App 背后,都有一群人轮班守着。半夜系统出问题,手机响的就是他们。Google 这本《SRE》里有四章专门讲这件事:怎么排班才不把人熬垮、警报响了第一步该干什么、一群人同时救火怎么不打架、以及每次响过的警报要不要记账。这几章合起来是全书最「不技术」的一部分——因为它管的是人。
系统崩了,公司派了一屋子最强的工程师去救,结果修得比只派两个人还慢。为什么?因为十个人各自打开笔记本,各查各的、各改各的:A 刚重启了一台机器,B 正好在往那台机器上导数据,C 以为是网络问题去动了配置,D 在给老板写邮件却拿到的是半小时前的情况。力气全用在互相抵消上。
过去救火靠「英雄」:某个待得最久、脑子里装着全部历史的人,一被叫醒就知道该看哪儿。这套模式有三个致命伤:英雄会累、会请假、会离职;新人永远学不到他脑子里的东西;而且没人知道这个月到底被叫醒了多少次——痛苦全被个人默默吸收,公司账上看不见,所以永远没人去修那个天天半夜响的破警报。
这几章的答案很朴素:抄消防队。真实火场上,最有经验的那个人不拿水枪——他站在外面当现场指挥,只负责「现在谁在做什么、下一步做什么」。拿水枪的是另一组人,而且只有他们能动阀门,别人再着急也不许伸手。还有一个人专门对外通报,让家属和记者拿到的是同一份最新说法。现场支一块白板,写着「起火点在哪、已经封了哪几层」——谁半路加入,看白板就能跟上,不用打断任何人问一遍。
另外两件同样重要:排班要养得住人——一个班被叫醒的次数得有上限,因为每次事故后都要坐下来好好复盘,堆多了就只能草草了事;每次警报都要记一笔账——响过几次、其中几次真需要人起床。记了账才看得见:有些警报响了整个季度,没有一次是真的;看见了,才好意思删掉它。
把救火从「靠某个人的记性」变成「一套谁都能跑的流程」:新人有路可学,老人有假可休,痛苦变成了能拿到会上讨论的数字。代价也很实在:这套流程本身有开销,小毛病也摆开指挥体系,纯属浪费。所以真正的手艺在于判断什么时候该升级、什么时候就地修掉。
救火不是比谁手快,是比谁不乱:指挥的人不动手、动手的人只有一组、对外只有一个口径、现场有一块谁都能看的白板。再加上排班养得住人、警报笔笔记账——这几件事,机器替不了。
想进到角色分工、具体阈值和示意图? → 切到精读版
你以为值班(on-call)是为了「修得快」,其实它是为了让系统和人都活得久。这四章把「救火」从个人英雄主义拆成一套可复制的工程制度:Ch11 把值班当成有容量上限的资源来排;Ch13 用三起真实事故说明紧急情况按「谁点的火」分类才有对策;Ch14 把消防系统的事故指挥体系(Incident Command System, ICS)搬进机房;Ch16 用工具把每次告警记成可统计的账——因为没量化的痛苦永远不会被修。
四章都在《SRE》Part III「实践」里:Ch11 开篇讲值班,Ch13 与 Ch14 相邻讲响应与协同,Ch16 紧跟在 Ch15「复盘文化」之后。合成一篇的理由:它们是同一条流水线的四段——排好班(11)→ 警报响了怎么响应(13)→ 多人协同怎么不打架(14)→ 把这次经历变成数据(16)。单看每章都薄,串起来才是 SRE 里唯一不能自动化的那条闭环。前接 Ch6「监控」(告警从哪来),对应现实里任何有 7×24 值班的团队。
典型的旧世界:一个人扛着 pager,脑子里装着全部历史;他被叫醒多少次没人统计,痛苦被个人吸收,所以那条「每晚两点准时响、响了也没事」的告警活了三年。事故真来了,一屋子人各查各的、各改各的——A 重启机器、B 正往那台机器灌数据、C 顺手改了配置、D 对外通报的是半小时前的状态。事后没人说得清改过什么,复盘写不出时间线,同一个坑第二年再踩一次。
不解决会怎样:可靠性上不去(没人知道该修什么),团队会烧穿——资深工程师因为睡不好觉而离职,带走脑子里唯一那份运行知识。
本章最反直觉的一句是:on-call 在设计上就应该只占 SRE 工作的少数。Google 的硬约束是运维类工作(含值班)不超过 50% 工时,目标值约 25%,剩下的必须用于工程改进——否则团队就退化成纯运维,可靠性再也不会变好。
由此推出两个必须同时管住的旋钮。数量(quantity):轮值人数得够,书里的经验下限是单站点 8 人、双站点各 6 人——低于这个数,人均在班时间压不下来,也扛不住请假与离职。质量(quality):每班被叫起的次数得有上限,Google 的经验值是一个 12 小时班次最多 2 起事故——认真做一次复盘约 6 小时,两起就吃完了班次余量;再多,复盘只能敷衍,这次事故就白疼了。
补偿也是个限流器:Google 对值班给调休或现金补偿,但设上限(约整体薪酬的 5%–6%)。这个设计有意为之——上限意味着一个人不可能靠多值班多挣钱,于是「谁都想多值班」这种把团队推向过载的激励从根上被掐掉。
还有「让人感到安全」这一层:肾上腺素上来时人会切到直觉反应(凭经验快速下手),而重压下的直觉常出错。本章的解药不是「让人别紧张」,而是给三样资源:清晰的升级路径、写好的处理流程、不追责的复盘文化。反方向也是病——运维负荷过低:系统太安静,值班人会生疏,得靠灾难演练和角色扮演演习养手感。
可带走的判据:人均每班被叫起超过 2 次、或轮值池不足 6–8 人,问题不在「再扛一下」,而在容量不够——要么加人,要么砍告警,要么把 pager 退回开发团队。
本章用三起 Google 真实事故给紧急情况分了三类:测试引发(为了暴露隐藏依赖而主动做的破坏性测试,影响范围超出预期)、变更引发(一次配置推送触发了全局性的崩溃,靠快速回滚在分钟级止血)、流程引发(自动化流程拿到了错误的输入,把远超预期数量的机器送进了回收流程)。
分类的价值在于对策不同:变更引发的,能不能快速回滚几乎决定全部损失,止血优先于查根因;流程引发的,缺的是自动化里那道「这个规模合理吗」的安全闸;测试引发的,缺的是测试本身的中止路径。
本章反复强调的两点:所有问题都有解——恐慌才是最大的敌人;以及把事故历史当资产(「记不住过去的人注定重演过去」)。具体做法是三条:留存并回读故障史、主动问那些「万一……会怎样」的不舒服问题、鼓励主动做破坏性测试——希望不是一种策略(hope is not a strategy)。
可带走的判据:任何一次变更或测试上线前,先回答「回滚路径是什么、多久能执行完」。答不上来,这次变更就不该推。
本章先解剖一起没人管的事故,指出三个反模式:过度聚焦技术问题(没人抬头看业务影响)、沟通糟糕(对内对外各说各话)、各自行动(freelancing)——每个人单方面改系统,彼此抵消。
解法借自美国消防的事故指挥体系(ICS),核心是责任的递归拆分:每个人都有明确角色,角色可以再往下分派;凡是没被分派出去的职责,默认都归指挥官。四个角色:
配套三件基础设施:公认的指挥所(书里偏好 IRC 这类文字频道——网络抖动时更抗得住、天然留全量日志供复盘、还能挂机器人自动记录)、实时事故文档(由 IC 维护、有模板,新加入的人读文档而不是打断别人问一遍)、明确的交接(IC 换班必须显式交出、接手方显式确认)。
「何时宣布事故」给了三条判据:要不要拉进第二个团队?是否已影响用户?集中分析一小时还没解决?任一为是就宣布。态度很明确——宁早不晚:给小事故保持秩序容易,给已蔓延的事故追加秩序很难。
可带走的判据:事故中如果有第二个人正在改系统,你的指挥体系就已经失效了——先把「谁是 Ops」这件事说清,再继续修。
本章的主张只有一句:要改进基线,先得测量基线。Google 为此做了两个工具。Escalator 解决「这条告警有没有人真的接手」——它被透明地加进告警的收件人里,追踪是否有人确认,没人确认就按路径升级(主班 → 备班 → 整个团队)。Outalator 解决「这些告警到底说了几件事」:
cause:network、action:ignored、bug:1234),先记下来、以后再归纳——比先设计一套完美分类法现实得多。意外收益是行为变了:数据一摆出来,「这条上季度响了一百多次、没一次需要人动手」就从抱怨变成可执行的删除提案。
可带走的判据:对每一条会叫醒人的告警,要能答出「上季度响了几次、其中几次真需要人动手」。答不出,就说明你还没有资格说「我们的告警是必要的」。
表 1 · 值班健康度的四个旋钮:拧错了会怎样(数字为《SRE》给出的 Google 经验值)
| 旋钮 | Google 的取值 | 拧太紧的代价 | 拧太松的代价 |
|---|---|---|---|
| 运维占比 | 上限 50% 工时,目标约 25% | 没人做工程改进,可靠性永远原地踏步 | 团队脱离生产,改出的东西不接地气 |
| 轮值人数 | 单站点 ≥8 人;双站点各 ≥6 人 | 人均在班太久,请假 / 离职就崩 | 轮次太稀,值班人手感生疏(运维负荷过低) |
| 每班事故数 | ≤2 起 / 12 小时班次 | 复盘只能敷衍——一次 6 小时的复盘做不完两起 | —(但要靠演练补手感) |
| 值班补偿 | 调休或现金,设上限(约薪酬 5%–6%) | 补偿太低会积压怨气 | 不设上限 → 有人靠多值班挣钱,团队被推向过载 |
表 2 · 同一起事故,有无指挥体系的差别(Ch14 的两次推演)
| 无人管的事故 | ICS 管起来的事故 | |
|---|---|---|
| 谁能改系统 | 谁着急谁改 → 互相抵消 | 只有操作组,其余人一律不许伸手 |
| 全局状态在哪 | 在各人脑子里,互相不一致 | 在实时事故文档里,新人自己读 |
| 对外说法 | 多个口径、还是旧数据 | 沟通角色单一出口、按节奏更新 |
| 换班 | 悄悄消失,上下文丢失 | 显式交接 + 接手方显式确认 |
| 代价 | 看似零开销,实际把时间烧在协调摩擦上 | 流程本身有开销:小故障摆全套是浪费 |
表 3 · 告警去留:用 Outalator 的长期数据判定
| 长期数据长这样 | 判定 | 动作 |
|---|---|---|
响得多、几乎全部 action:ignored | 纯噪声 | 删掉或降级为工单,别再叫醒人 |
| 响得少、每次都需要人动手 | 健康的呼叫 | 保留;补一份处理手册 |
| 响得多、每次都需要人动手 | 底层有真问题 | 别调阈值——去修根因,或用错误预算换排期 |
| 几乎不响,也没人练过 | 运维负荷过低 | 靠灾难演练与角色扮演演习养手感 |
这四章是今天整个「事故管理」行业的源头文本。IC / Ops / Comms 的角色分工已是 PagerDuty、Atlassian、Incident.io 等产品的默认模型;Escalator 的「确认 / 升级」语义成了值班排班工具的标配;Outalator 则是现代告警平台 incident grouping 与告警疲劳报表的直系祖先。面试或架构评审里被问「你们怎么值班」,答得出「每班事故数上限、可操作率、谁是唯一能改系统的人」,就已经甩开了「我们有个群,出事在群里喊」。
① 这四章是同一条闭环:排班(11)→ 响应(13)→ 协同(14)→ 记账(16),是 SRE 里唯一不能自动化的那部分。
② 值班在设计上就该是少数工作:运维类占比上限 50%、目标约 25%,其余必须留给工程改进。
③ 值班容量有硬下限:单站 8 人 / 双站各 6 人;每班事故上限 2 起,因为一次认真复盘要 6 小时。
④ 补偿设上限(约薪酬 5%–6%)是故意的限流器,掐掉「多值班多挣钱」这种推向过载的激励。
⑤ 让人感到安全靠三样:清晰升级路径、写好的处理流程、不追责的复盘;负荷过低也是病,靠演练治。
⑥ 紧急事故按「谁点的火」分三类:测试引发 / 变更引发 / 流程引发;变更类事故的胜负全在回滚速度,止血优先于查根因。
⑦ ICS 四角色:IC 持全局不动手、操作组唯一能改系统、沟通唯一对外、规划管长尾;配指挥所 + 实时文档 + 显式交接。
⑧ 宣布事故的三条判据:要不要拉第二个团队 / 用户是否已受影响 / 集中分析一小时还没解——宁早不晚。
⑨ Ch16 的一句话:没量化的痛苦不会被修。Escalator 管「有没有人接手」,Outalator 把告警聚合成事故、打标签、做长期统计。
⑩ 对每条会叫醒人的告警,都要答得出「上季度响几次、几次真需要动手」——答不出就还没资格说它必要。