一粟 · yisu.app
· 11 min read
复盘方法

关于「在事故中学习」,我们做错的和做对的

事故复盘是工程师最宝贵的成长机会,但 80% 的复盘都没真正"学到位"。一份关于复盘方法论的非技术讨论。

过去六年我参与过上百次事故复盘。回头看,绝大多数复盘都没"学到位"——同样的错误两三个月后会再出现一次。这件事让我反思:复盘本身是个被严重低估的工程能力。本文不是技术讨论,是关于"如何从事故里真正学到东西"的方法论。

复盘失败的三种典型模式

复盘"走过场"有几种常见形态:

  1. 找替罪羊:定位到某个人"按错按钮",写"加强培训"就结束。
  2. 归因技术:定位到某个组件"出 bug",写"已升级版本"就结束。
  3. 流水账:按时间线复述事件,列几十条 follow-up,但不讨论"为什么没早发现"。

这三种都"做完"了复盘,但都没"学到"。因为它们回答的是"发生了什么",不是"为什么没避免"。

复盘真正的目标

复盘的目标不是"找出谁错了",是"找出系统的盲点"。每次事故都是一次"系统在某条件下暴露缺陷"的实验。复盘要做的,是把这次实验的结论沉淀下来。

好复盘回答三个问题:这次事故告诉我们系统的哪个盲点?这个盲点还有哪些其他可能触发场景?怎么让系统对这类盲点有免疫力?

对的事故时间线

时间线不是"流水账"。它要包含三类信息:

  • 发生了什么:服务 X 在 T 时刻返回 5xx,持续 Y 分钟。
  • 谁在做什么:oncall 在 T+5 触发降级,DBA 在 T+10 扩容。
  • 为什么这么慢:告警延迟 N 分钟,定位耗时 M 分钟。

第三类才是复盘的"金矿"。它告诉你"我们的发现机制哪里慢了"。

根因分析的层次

根因不是单点。我习惯用"五层问":

  1. 触发层:什么直接导致了故障?(某次配置 push)
  2. 防线层:为什么没拦住?(CI 没校验)
  3. 检测层:为什么没早发现?(告警阈值太高)
  4. 响应层:为什么恢复慢?(oncall 不熟悉这个服务)
  5. 架构层:为什么这个设计脆弱?(单点依赖)

每一层都对应一类 follow-up。只做第一层的复盘,等于"把锅推给最后一个动手的人"。

follow-up 的纪律

复盘的 follow-up 是最容易"烂尾"的环节。我们的纪律:

  • 每条 follow-up 必须有 owner 与 due date。"团队"不算 owner。
  • follow-up 必须可验证。"加强测试"不算 follow-up,"在 CI 里加 X 检查"才算。
  • 每月 review follow-up 完成率,< 70% 团队要解释。
  • 已完成的 follow-up 要验证有效性。不能"加了告警"就完事,要"实际触发过"才算。

"无指责"文化的真意

"无指责"不等于"不追责"。它的真意是:"理解人为什么会犯错,然后让系统不依赖人不犯错"。

真实场景:某个 oncall 半夜两点误删了一个 server 块,导致 5 分钟 502。"无指责"复盘不是"没事,下次注意",而是问"为什么半夜两点让一个人改线上配置?为什么没有 review 机制?为什么删除前没有 dry-run?"

把"个人错误"转化为"系统改进",是无指责复盘的核心。

几条反直觉的经验

  • 频繁小事故比少有大事故更值得关注。小事故是"系统在告诉你边界在哪",大事故往往是小事故积累的爆发。
  • 不要太快定根因。第一次复盘找到的根因,往往只是"触发点"。再问三层才能找到"系统盲点"。
  • 复盘后 3 个月回看一次。看 follow-up 是否真的生效,看同类事故是否再出现。

几条复盘纪律

  1. 72 小时内开。再晚记忆就模糊。
  2. 所有相关方都到场。不能只 SRE 开。
  3. 必须有书面文档。会议不算复盘。
  4. 对外公开。让其他团队也能学。
  5. 不追个人责任,但追"流程责任"。

给团队的简短建议

  • 复盘不只看"发生了什么",要看"为什么没早发现"。
  • 根因要问五层,不要停在第一层。
  • follow-up 要可验证、有 owner、有 due date。
  • 复盘后 3 个月回看一次,确认真学到。

复盘是工程师最便宜也最被低估的成长方式。它不花钱、不换工具、不重构架构,只是把"已经发生过的事"认真看一遍。但认真看一遍的纪律,是大多数团队没有的。把它做成纪律,团队的成长速度会质变。