【背景】 15 年 SRE,换过 4 家公司。每家的 runbook 目录里都有十几篇甚至几十篇操作手册:MySQL 主从切换、Kafka 分区 rebalance、Pod OOM 应急扩内存、TLS 证书续签、连接池打满紧急扩容……
但真正在凌晨 3 点的 P0 里,被 on-call 工程师翻出来、照着执行的,我数过——不超过 3 篇。大多数 runbook 写完那天之后,再也没被打开过。
我见过两种极端:
- 一家公司 runbook 写得极其详尽(带截图、每条命令的预期输出、回滚步骤),但最后更新停留在 2 年前,架构已经换了 3 轮。事故里工程师打开一看,命令里的端口号、服务名都不对了,最后还是靠口口相传的"老张的经验"救的。
- 另一家公司 runbook 只有一行:"重启。"但每次事故响应反而最快——因为工程师知道该找谁、该按什么顺序操作,runbook 只是"心理安慰"和"合规留痕"。
【常见分歧 / 几种做法】
- runbook = 操作手册:写清楚每一步命令、预期输出、回滚步骤。适合"新人 on-call"和"跨团队协作"场景。
- runbook = 决策树:只写"看到什么现象 → 判断什么 → 做什么动作",不写具体命令。适合团队内熟练度高、人员流动小的场景。
- runbook = 自动化的过渡态:runbook 本质上是"人脑 runbook → 脚本 runbook"的中间产物,最终目标是把操作脚本化,runbook 只留"异常处理分支"和"人工决策点"。
- runbook 不重要:真正重要的不是文档,而是团队的"肌肉记忆"和"on-call 培训"。文档只是备份,是合规需要,不是工程需要。
【我的倾向与理由】 我偏向第 3 种,但有一个前提:runbook 的生命周期必须和代码一样管理——有 owner、有 review、有过期机制。
具体做法(我团队实际在用的,效果一般但比"不管"好):
- 每篇 runbook 头部有一个
last_verified字段,超过 90 天未验证的自动标黄(Confluence 宏实现的,不复杂)。 - 每次 P0/P1 事故后 48h 内,复盘会的第一项议程不是"根因分析",而是"runbook 里有没有覆盖这个场景?没有就当场补,有就照着跑一遍,把偏差写进去"。
- 每季度做一次"runbook 盲演":随机抽 2 篇,让 on-call 工程师在没有提示的情况下照着执行(非生产环境)。执行不了的,当场改。这一步最容易被砍,因为"没时间"。
但我也承认一个矛盾:如果 runbook 最终都变成了脚本,那"人"的角色就只剩"判断该跑哪个脚本"和"处理脚本没覆盖的异常"。这时候 runbook 的价值是不是已经退化成"一个 if-else 列表"?而 if-else 列表放在代码里不是更合理吗?
【补充:runbook 的量化验收标准——别再用"写了没"来度量】
之前我只说"效果一般",这里补一组我们团队 2024 Q1–Q3 跑下来的真实数据,看看 runbook 到底"值不值":
| 指标 | 2024 Q1(无量化) | 2024 Q3(引入验收标准后) | |---|---|---| | P0/P1 事故中 runbook 被实际打开的次数 | 7/14(50%) | 5/9(56%) | | 打开后"照着执行成功"的比例 | 2/7(29%) | 4/5(80%) | | 事故 MTTR(中位数) | 42 min | 18 min | | runbook 总数 | 23 篇 | 11 篇(砍了一半) |
关键变化不是"写得更多",而是砍掉了 12 篇从没被打开过的 runbook,把维护精力集中在真正被翻到的 11 篇上。MTTR 从 42 min 降到 18 min,核心原因是"照着执行成功率"从 29% 提到 80%——不是 runbook 变多了,是变准了。
量化验收标准(我们实际在用的 4 条):
- 打开率:近 90 天内至少被 1 次事故/演练打开过,否则进入"待淘汰"队列;
- 执行成功率:盲演中"从打开到执行完第一步命令"不超过 2 min,否则说明文档结构有问题(找不到关键步骤);
- 偏差率:执行过程中"文档写的和实际不符"的步骤占比 < 10%,超过则整篇重写;
- 脚本化率:可自动化的步骤(重启、扩容、切流)必须有对应脚本,runbook 里只留"执行脚本 + 预期输出 + 失败分支",不手敲命令。
这 4 条不是"写完再检查",是每季度盲演时逐条打分,不及格的 runbook 要么改、要么砍。
【补充:runbook 与 runbook-as-test 的边界】
上面提到"runbook 最终变成脚本",这里展开一个容易混淆的边界:
runbook-as-test(把 runbook 变成自动化测试)和 runbook-as-runbook(人执行的步骤)是两回事,不要混。
- runbook-as-test:CI/CD 流水线里跑
verify_mysql_failover.sh,验证"主从切换脚本在 staging 能跑通"。这是回归测试,跑的是"代码"。 - runbook-as-runbook:凌晨 3 点,脚本挂了,人打开 runbook 看"手动切换的 5 个步骤"。这是人的操作手册,跑的是"判断力"。
边界判据:如果一个 runbook 步骤里 90% 以上都是"执行某条命令 + 看输出 + 判断下一步",那它应该变成脚本(runbook-as-test);如果 90% 以上都是"判断该不该做、跟谁确认、影响面评估",那它必须留给人(runbook-as-runbook)。
我们团队现在 11 篇 runbook 里,7 篇是"人判断 + 跑脚本"(混合态),4 篇是纯"人判断"(比如"要不要做数据回滚"这种没有标准答案的决策)。纯操作手册(全手敲命令)的已经 0 篇了——要么脚本化了,要么砍了。
【想听大家在什么场景下怎么选】
- 你们团队的 runbook 是"活文档"还是"考古化石"?最后更新是什么时候?
- 有没有过"runbook 写得很详细但事故里根本没用上"的经历?当时是怎么救的?救完之后有没有回头改 runbook?
- 你们把 runbook 脚本化的比例大概是多少?剩下没脚本化的部分,是"不值得"还是"来不及"?
- 一个新 on-call 工程师接手值班,你给他看 runbook 还是给他看"历史事故复盘文档"?为什么?
- 你觉得 runbook 的"保质期"应该是多久?谁来负责续命?
- (新增)你们有没有用"打开率 + 执行成功率"来淘汰 runbook 的经验?砍掉过时 runbook 比维护所有 runbook 难还是容易?