跳到主要内容

运维篇 · 04 · 故障复盘

本章目标

让每次故障成为团队成长的养分,而不是找人背锅的会议。

一、复盘的原则(最关键)

1.1 对事不对人(Blameless Culture)

❌ 反例

"这个故障是张三写的代码有 Bug 导致的,以后张三要更小心。"

✅ 正例

"这个 Bug 能溜到线上,说明:代码评审没覆盖到、测试没覆盖到、灰度没发现。 我们需要改进这三个环节的检查清单。"

为什么

  • 任何一个"个人失误"背后都是流程漏洞
  • 如果怪人,大家会隐瞒故障,问题反而更严重
  • 追责文化会杀死主动改进的意愿

1.2 复盘的目的

  • 找出系统性问题
  • 改进流程和工具
  • 沉淀知识
  • 降低未来故障概率

不是

  • 找替罪羊
  • 考核绩效
  • 拿来追溯责任

二、复盘流程

故障结束 ──► 48h 内:初稿 ──► 召开复盘会 ──► 确定改进项 ──► 跟踪执行

2.1 时机

  • 24-48 小时内召开:记忆清晰
  • 不超过 1 周:否则细节遗忘
  • 参与者:IC、Tech Lead、当班人员、相关模块 owner

2.2 复盘会议议程(60 分钟)

时间环节产出
5 min开场与规则(对事不对人)-
10 min故障时间线(客观还原)时间线图
15 min根因分析(5 Why)根因清单
15 min改进措施讨论Action Item
10 min分工与时限责任人 + deadline
5 min总结会议纪要

2.3 复盘报告模板

# 故障复盘: SEV-1 订单服务不可用 (2026-04-15)

## 摘要

**严重度**: SEV-1
**持续时间**: 1 小时 15 分钟
**影响范围**: 全站下单不可用,影响约 15,000 用户
**业务影响**: 估算损失 ¥50,000
**根本原因**: 数据库连接池配置错误,导致新版本启动后耗尽连接

## 时间线

| 时间 | 事件 | 责任人 |
|------|------|-------|
| 2026-04-15 10:00 | 开始发布 v1.2.1 | @ops |
| 10:15 | 灰度 10% | @ops |
| 10:30 | 监控告警: API 5xx 飙升 | 监控 |
| 10:32 | 值班人确认故障 | @alice |
| 10:35 | 故障群创建,指定 IC | @alice |
| 10:45 | 初步定位到新版本 | @bob |
| 11:00 | 决定回滚 | @ic |
| 11:15 | 回滚完成 | @ops |
| 11:30 | 服务恢复 | - |
| 11:45 | 持续观察稳定,故障结束 | @alice |

## 详细经过

### 发布阶段
v1.2.1 修复了一个支付相关 bug,按流程灰度发布...

### 故障触发
灰度 10% 后,新版本实例的数据库连接池很快打满...

### 处置过程
@bob 首先怀疑是代码 Bug,查看最近变更...
@alice 作为 IC 决定先回滚,后定位根因...

## 根因分析(5 Why)

**问题**: 为什么订单服务不可用?

- **Why 1**: API 5xx 率飙升
- **Why 2**: 数据库连接不可用
- **Why 3**: 连接池耗尽
- **Why 4**: 新版本连接池配置从 50 改成 5
- **Why 5**: CR 时改了默认值,但没人注意到

**根因**: 配置变更**没有专项评审机制**,关键参数变更易被忽视。

## 做得好的地方

- ✅ 监控及时告警(2 分钟内)
- ✅ 值班人响应快(5 分钟内)
- ✅ IC 决策果断(15 分钟决定回滚)
- ✅ 通报节奏好,对外沟通及时

## 做得不好的地方

- ❌ 代码评审漏掉了连接池配置变更
- ❌ 灰度 10% 的观察窗口太短(15 分钟就扩大)
- ❌ 没有针对"配置变更"的自动化检查
- ❌ Runbook 里没有"连接池耗尽"这个场景

## 改进项(Action Items)

| # | 改进项 | 负责人 | 截止日期 | 跟踪 |
|---|-------|-------|---------|------|
| 1 | 关键配置变更加"双人评审"流程 | @tech-lead | 2026-04-22 | 🟡 进行中 |
| 2 | 灰度延长到 30 分钟最小观察 | @ops-lead | 2026-04-20 | ✅ 完成 |
| 3 | 加 CI 检查: 关键配置变更必须 trigger warning | @platform | 2026-05-01 | 🟡 |
| 4 | 补充 Runbook: 数据库连接池耗尽处置 | @alice | 2026-04-18 ||
| 5 | 加监控: 连接池使用率实时告警 | @bob | 2026-04-20 | 🟡 |

## 度量与教训

### 响应时间
- 发现到确认: 2 min (目标 5 min) ✅
- 确认到决策: 25 min (目标 15 min) ❌ 需改进
- 决策到恢复: 30 min (目标 30 min) ✅

### 关键教训
1. **配置和代码是同等重要的资产** — 要有同样的评审和审计机制
2. **灰度时长不能只看比例** — 时间维度也要考虑
3. **现象→动作→根因 是迭代过程** — 先恢复再定位是对的

三、5 Why 分析法

3.1 核心思路

连续问 5 次"为什么",挖到根本原因。

3.2 示例

问题: 网站打不开

Why 1: 为什么打不开?
→ Web 服务器返回 502

Why 2: 为什么返回 502?
→ 应用进程崩溃

Why 3: 为什么应用进程崩溃?
→ OOM(内存溢出)

Why 4: 为什么 OOM?
→ 某个请求加载了整张百万级大表到内存

Why 5: 为什么会这样?
→ 代码里用了 findAll() 而不是分页查询

根因: 缺少对"无边界查询"的代码检查规则
改进: lint 规则加 findAll() 警告

3.3 5 Why 的常见误区

  • 停得太早:停在"Bug"这种结论上
  • 只看技术:忽略流程、组织、文化
  • 分支太散:没有聚焦到一个主要链路
  • 找人背锅:第 5 个 Why 变成"张三不小心"

四、根因分类

4.1 技术类

  • 代码 Bug
  • 配置错误
  • 容量不足
  • 依赖故障
  • 数据异常

4.2 流程类

  • 评审不严
  • 测试覆盖不足
  • 发布流程漏洞
  • 监控告警缺失
  • Runbook 不完善

4.3 组织类

  • 职责不清
  • 沟通不畅
  • 知识断层
  • 培训不够
  • 值班制度漏洞

4.4 文化类

  • 追责文化导致隐瞒
  • 压力大导致短视
  • 追求上线速度牺牲质量

好的复盘应该覆盖所有 4 类,不能只停在技术层。

五、改进项(Action Item)的管理

5.1 AI 的 SMART 原则

每个改进项必须:

  • Specific: 具体(不是"加强监控",而是"加 XXX 告警规则")
  • Measurable: 可衡量(可以验证是否完成)
  • Assignable: 有责任人
  • Realistic: 可实现
  • Time-bound: 有截止日期

5.2 跟踪机制

  • 录入 Issue 系统
  • 关联到团队周会
  • 每周 review 一次进度
  • 逾期升级

5.3 完成率

  • 目标:> 90% 按时完成
  • 低于 80% 要分析原因

六、知识沉淀

6.1 故障数据库

所有故障复盘报告汇总到一个知识库:

docs/
└── postmortems/
├── README.md ← 索引
├── 2026/
│ ├── 04-15-order-down.md
│ ├── 04-20-payment-timeout.md
│ └── ...
├── 2025/
└── lessons-learned.md ← 经验提炼

6.2 跨故障的模式分析

每季度/每年做一次:

  • 故障按类型分布(哪类最多?)
  • 根因分布(流程 / 技术 / 组织?)
  • MTTR 趋势(有没有在提升?)
  • 改进项完成率
  • 重复故障情况(是否同类问题反复发生)

6.3 Runbook 更新

每个故障后必须问

  • 这个场景 runbook 里有吗?
  • Runbook 里的步骤是否起到了帮助?
  • 需要新增 / 更新什么?

七、故障度量指标

7.1 事后指标

指标定义目标
MTTDMean Time To Detect(发现时间)
MTTRMean Time To Recover(恢复时间)
MTBFMean Time Between Failures
改进项完成率按期完成 / 总数> 90%
重复故障率同类问题再次发生< 5%

7.2 用这些指标做什么

  • 看团队趋势(变好还是变差)
  • 横向对比(不同服务)
  • 决定投资方向(哪里最需要加强)

八、配套资源