好的排障不留痕迹
一句话总结
用 30 分钟精确缩小范围并修好问题的人,与摸索三小时后偶然修好的人,最终提交看起来完全一样。因此,不留下记录,个人能力和组织资产都无法积累。
为什么需要了解这一点
调试能力没有随着资历自然增长,有三个原因。
第一,几乎没有地方会明确教授调试。人们学习语言和框架,却只能在旁观中学会缩小范围的流程。
第二,反馈机制设置错误。症状消失就会得到奖励,即使不知道症状为什么消失,也会得到同样的奖励。 因而,靠运气修好的经验会被误认为能力。
第三,优秀调试不会留下痕迹。组织很难识别这种能力;无法识别,也就无法培养。
对此只有一种应对方式:留下痕迹。
缩小范围的流程有名称
要留下记录,首先必须有流程。给有经验者无意识执行的动作命名,才能使它可以被学习。
二分查找。 把请求经过的层次对半切开。若路径是客户端 → 网关 → 服务 → DB,先从网关内部直接调用服务。成功则问题在前半段,失败则在后半段。每次都能把候选范围减半;八层只需三次就能缩小到一层。
差异缩减(delta debugging)。 当既有成功样例又有失败样例时使用。逐项删除两种请求之间的差异,找到哪个差异消失时,症状也随之消失。最后可能只剩一个请求头、一个字段或一个时间点。
对齐时间轴。 把部署、配置变更、流量增长的时间与症状开始时间排在同一条线上。大多数故障都始于某项变化之后。准确知道“从什么时候开始”,就等于回答了“由什么引起”的一半。
反转假设。 若超过 30 分钟仍无法缩小范围,很可能有一项自认为确定的事情其实是错的。“DNS 当然正常”“配置已经生效”“版本肯定正确”——逐一实际验证这些假设,通常就会从这里找到原因。
记录格式——一页就够
写得太长就没人愿意写。实务中真正能够长期维持的格式,大致如下。
## 증상
결제 완료 화면에서 간헐적 500 (약 20%)
## 재현
for i in $(seq 20); do curl -s -o /dev/null -w '%{http_code}
' -X POST https://stg/api/pay -d @fixtures/pay.json; done
→ 20회 중 4~6회 500
## 배제
- 인증: 401/403 이 로그에 0건
- 네트워크: 같은 요청을 게이트웨이 안에서 직접 → 같은 비율로 실패
- 데이터: 실패한 요청의 body 가 성공한 것과 바이트 단위로 동일
## 원인
결제 서비스 파드 3개 중 1개만 옛 설정(타임아웃 1초)으로 떠 있었다.
ConfigMap 을 바꾼 뒤 rollout restart 를 하지 않아 그 파드만 옛 값을 안고 있었다.
## 수리 전후
전: 20회 중 5회 실패 / 후: 40회 중 0회 실패 (같은 명령)
## 다음에 이걸 막는 것
- [ ] ConfigMap 해시를 파드 애노테이션에 넣어 변경 시 자동 재시작 (담당: 배포팀, 3/25)
“下次如何防止”正是这份文档的价值。只记录原因,最多能在第二次遇到同一故障时提供搜索结果;连预防措施也记录下来,才能消灭第二次故障。
设定时间盒
在未能缩小范围的情况下让时间不断流逝,是调试最大的成本。因此应事先定好时间盒。
| 已用时间 | 应做的事 |
|---|---|
| 15 分钟 | 把目前排除的内容写下来;书写时会看见遗漏的层次 |
| 30 分钟 | 实际验证一个自认为确定的假设 |
| 45 分钟 | 请别人加入;有一半时候,在解释过程中自己就会发现问题 |
| 60 分钟 | 查看是否有绕行方案;查明原因与恢复服务是两回事 |
最后一行尤其重要。处理事故时,先恢复,后查因。明明可以通过回滚在五分钟内恢复,却为了找原因耗费一小时,是错误的优先级。
工作原理
FDE 应留下四类记录。
复现命令。 一条能触发症状的最小命令。有了它,就能使用同一标准判断是否修好;没有它,最多只能说“好像修好了”。
排除列表。 已经检查并排除的层次及其依据。一行就够,例如 auth — 401/403 이 로그에 한 건도 없음。
测量值的前后对比。 修复前 20 次中失败 5 次,修复后 20 次中失败 0 次。关键是两个数字采用相同方法测得。
人员离开后仍然留下的文档。 FDE 的成功标准很特别:没有我也能运转才算成功。如果驻场结束当天系统也一起停摆,那就不是交付,而只是出租。
实际工作中的表现
在交接文档中,客户最经常重新打开的不是架构图,而是故障运行手册:针对常见症状,写明前 30 分钟该做什么。没有运行手册的系统,是无法交接的系统。
交付文档当天,不应只把文档交出去;还应让客户工程师按照运行手册亲自处理一个故障场景,完成演练,才算闭环。读懂与真正动手是两回事。
比记录格式更重要的是时机。交接文档应从项目中期开始积累,而不是到最后一周才写。最后一周集中编写的文档,无一例外会遗漏“哪些事情行不通”。因为到那时,作者早已习惯这些例外,不再觉得它们特殊。
下个练习将做什么
实际留下上述四类记录。最后,评分器会扮演下一位接手者:它会在不是你的 Shell 的干净环境中,再次运行你写下的复现命令。只有在那里得到相同数字,记录才真正称得上记录。