排障是控制变量的过程
排障慢下来通常不是因为问题难,而是因为把推断当成了事实:以为两台主机配置相同、以为变量取到了预期值、以为改的那一项就是关键项。一旦这些「以为」进入推理链条,后续所有判断都建立在沙子上。可控的做法是把过程结构化——先把已确证的事实与待验证的假设分开记录,再每次只改动一个变量并记录改动前后的观测结果,让因果关系可被证实或推翻。
基本信息
| 适用对象 | 任何系统性故障的定位过程 |
|---|---|
| 核心方法 | 区分事实与假设、一次只改一个变量 |
| 记录要求 | 每次改动前后都留下观测结果与时间点 |
| 常见偏差 | 只收集支持自己判断的证据 |
| 关键前提 | 确认讨论的是同一主机、账号与版本 |
事实核对清单
- 同一对象:出错的主机、账号、路径、版本是否与你验证时完全一致
- 同一环境:测试与生产、容器与宿主机之间环境变量与依赖是否相同
- 同一时刻:日志时间点与操作时间是否对齐,时区是否一致
- 同一输入:触发问题的请求或参数是否被完整复现
- 同一版本:二进制、配置与基线是否都确认过版本信息
- 同一视角:客户端与服务端看到的现象是否一致,还是只在某一侧出现
可复现的最小验证
可复现的最小验证
uname -a && cat /etc/os-release | head -3 # 固定环境事实,避免跨主机混淆
date && timedatectl status | head -3 # 时间与时区对齐
echo "$TARGET_ENV / $APP_VERSION" # 打印关键变量,确认取值非空
set -x; mycmd --dry-run; set +x # 记录实际执行的命令
diff -u config.bak config.now # 两次执行的差异,确认改动只有一处
journalctl --since '10 min ago' -p warning | tail -20 # 改动时间窗内的日志事实与假设的区分
| 表述 | 性质 | 处理方式 |
|---|---|---|
| 服务在 10:02 重启过 | 事实 | 记录并作为时间线锚点 |
| 应该是配置改动引起的 | 假设 | 设计实验验证或推翻 |
| 两台主机配置相同 | 未验证 | 逐项核对关键配置后再使用 |
| 日志里没有报错 | 部分事实 | 确认日志级别与时间窗覆盖范围内 |
| 重启后就好了 | 现象 | 追问为什么,避免复发 |
写下预期结果再执行验证,是抵抗确认偏误最有效的一步:先说清「如果判断成立,这次执行应该看到什么」,再执行。结果与预期不符时,说明判断需要修正,而不是去解释它为什么仍然算符合。
排障中顺手记录时间点与命令输出,成本很低但价值很高:故障往往间歇出现,等到需要复盘时,唯一能依靠的就是当时留下的原始记录,而不是几天后的回忆。