事故复盘(Postmortem)
指导 Agent 用时间线、影响指标、根因分析与改进行动填满复盘文档:坚持无指责文化,用五问法追问系统性因素而非个人;行动项可验收、可跟踪。
摘要段含开始/恢复时间、受影响用户或交易占比、是否数据损坏;敏感细节脱敏后仍可支撑内部学习。
根因区分直接原因与系统性因素(监控盲区、发布流程、容量规划);五问法内嵌为可验证链条,避免「问了五句空话」。
行动项须可跟踪:负责人、截止日期、验证方式;与已有工单或 epic 互链,防止复盘后石沉大海。
无指责原则(Blameless)
聚焦系统与流程
文档描述「什么机制失效」:告警是否迟到、Runbook 是否缺失、审批是否成瓶颈。不将根因写成某人「粗心」;若涉及人为操作,写清培训、工具或检查单缺口。
心理安全与责任
鼓励完整时间线与诚实记录;责任人用于行动项 owner推进改进,而非问责清单。对外沟通口径与内部学习材料可分层脱敏。
- 检测:为何未能更早告警或自动缓解——从信号、阈值、on-call 路由追问。
- 响应:升级路径是否顺畅;决策延迟是否因信息不全或权限不清。
- 沟通:内外公告时间点与措辞是否恰当;是否避免指责性用语。
完整事故复盘文档模板(Markdown,可直接用于 Confluence / Notion):
# 事故复盘:[服务名] [简短描述]
**事故 ID**: INC-2024-0315
**严重等级**: P1
**起止时间**: 2024-03-15 14:02 UTC — 2024-03-15 16:48 UTC(2h 46min)
**撰写人**: @on-call-engineer
**复盘会议**: 2024-03-17 10:00 UTC
## 摘要
支付服务错误率在 14:02 突增至 12%,持续 2h46min,影响约 8% 的结账请求。
无数据损坏,所有失败请求均已向用户返回明确错误信息。
## 事故严重等级定义
| 等级 | 标准 |
|------|------|
| P0 | 核心服务全量不可用,影响 >50% 用户,无变通 |
| P1 | 核心路径严重降级,影响 >20% 用户,SLO 违约 |
| P2 | 局部功能受损,有变通,SLO 未违约 |
| P3 | 体验下降,无用户可见错误 |
## 时间线(UTC)
| 时间 | 事件 |
|------|------|
| 13:45 | 部署 payment-svc v2.4.1 至生产(滚动发布) |
| 14:02 | 错误率告警触发(阈值 >1% 持续 5min) |
| 14:08 | on-call 认领,开始排查 |
| 14:25 | 确认与新版本相关,决定回滚 |
| 14:35 | 回滚完成,错误率开始下降 |
| 14:48 | 错误率恢复正常,告警解除 |
## 影响评估
- 影响用户:~8% 的结账请求失败(约 2,400 笔交易)
- SLI 影响:成功率从 99.95% 降至 88%,违反 99.9% SLO
- 数据完整性:无数据损坏,幂等性设计保证无重复扣款
## 根因分析(见下方五问法)
**直接原因**:v2.4.1 引入的数据库连接池配置错误导致连接耗尽
## 行动项
见下方 SMART 格式
若组织仍需合规调查,与无指责复盘流程分离:复盘产学习,调查走独立通道,避免混写进同一份对外稿。
五问法(Five Whys)
从可观察现象出发,每一层「为什么」应对应可核对的证据(日志、配置、变更记录、监控截图)。若某一问出现多个并列原因,分支记录或先收敛主路径再补「并列因素」小节。
真实事故案例:支付服务连接池耗尽,完整走完 5 步:
## 五问法根因分析
**现象(起点)**
支付 API 错误率在 14:02 突增至 12%,日志显示 "connection pool exhausted"
**Why 1**: 为什么连接池耗尽?
→ 数据库连接池 max_size 从 50 被错误设置为 5
证据:`kubectl get configmap payment-db-config -o yaml | grep max_pool_size` → 输出 5
变更记录:v2.4.1 PR #892 修改了 db_config.yaml
**Why 2**: 为什么配置错误未被发现?
→ PR 审查通过了,但 CI 没有对连接池参数做范围检查
证据:CI 流水线日志显示 config validation 步骤跳过了 pool 参数验证
**Why 3**: 为什么 CI 没有验证连接池参数?
→ 配置校验脚本只检查必填字段,没有检查数值合理范围
证据:scripts/validate-config.sh 中 max_pool_size 仅检查 is_set,未检查 >=10
**Why 4**: 为什么校验脚本不检查数值范围?
→ 该脚本最初只为检查必填字段,从未更新以覆盖业务约束
证据:git log scripts/validate-config.sh 显示最后修改是 18 个月前
**Why 5**: 为什么配置变更没有 staging 环境的压测门禁?
→ 连接池配置被归类为"低风险变更",豁免了 staging 验证
证据:发布策略文档中 db_config.yaml 变更级别标记为 "minor"
**系统性贡献因素**:
1. 配置参数缺少范围约束的自动化验证
2. 变更风险分类规则过于粗粒度
3. 连接池耗尽告警阈值(>1% 持续 5min)过于保守,应提前检测
- 避免循环论证:下一问应比上一问更靠近系统设计或流程,而非同义反复。
- 第五问左右宜落到可改项:监控、SLO、发布门禁、容量模型、文档或培训。
- 与「直接原因」区分:直接原因往往是触发事件;五问链用于暴露贡献因素与防御层失效。
复盘主流程(skill-flow-block)
[ 检测:告警 / 用户报告 / 内部发现 ]
│
▼
┌─────────────┐ 止血优先:限流、回滚、开关、隔离坏实例
│ 稳定与缓解 │──── 记录:时间戳、操作者、命令或工单链接
└─────────────┘
│
▼
┌─────────────┐ UTC + 本地时区;关键决策、升级、对外公告
│ 时间线 │──── 变更、部署、配置、依赖方事件对齐到同一时间轴
└─────────────┘
│
▼
┌─────────────┐ 影响:用户/交易比例、SLI、数据完整性
│ 影响评估 │──── 无指责措辞:失效模式与检测缺口
└─────────────┘
│
▼
┌─────────────┐ 直接原因 + 五问链 → 系统性贡献因素
│ 根因分析 │──── 区分「触发」与「为何未更早发现/未自动恢复」
└─────────────┘
│
▼
┌─────────────┐ owner / due / 验收标准 / 工单链接
│ 行动项 │──── 预防复发 + 缩短检测/恢复时间(可选优先级)
└─────────────┘
│
▼
┌─────────────┐ 内部分享;敏感细节脱敏;可选对外摘要
│ 传播学习 │
└─────────────┘
行动项与跟踪
每条行动对应「如何证明做完」:合并 PR、监控面板更新、Runbook 修订编号、演练通过记录。Agent 起草时应显式写「无 owner 则标 TBD + 建议角色」,避免悬空句。
SMART 格式行动项示例(对应上方事故):
## 行动项(SMART 格式)
### 短期(1周内)
| # | 行动 | 负责人 | 截止日 | 验收标准 | 工单 |
|---|------|--------|--------|----------|------|
| 1 | 为 max_pool_size 添加范围校验(≥10)到 CI | @backend-dev | 2024-03-22 | CI 对 max_pool_size<10 的配置返回非零退出码 | #1456 |
| 2 | 修订发布策略:db_config 变更升级为"中风险"需 staging 验证 | @release-eng | 2024-03-22 | 策略文档 PR 合并,release captain 确认知悉 | #1457 |
### 中期(1个月内)
| # | 行动 | 负责人 | 截止日 | 验收标准 | 工单 |
|---|------|--------|--------|----------|------|
| 3 | 添加连接池使用率告警(>80% 持续 2min → warning) | @sre-team | 2024-04-15 | Grafana 面板中可见,测试告警触发并通知 on-call | #1460 |
| 4 | 为所有 DB 配置参数补充 JSON Schema 校验规则 | @platform | 2024-04-15 | schema 文件 PR 合并,CI 集成通过 | #1461 |
### 未决问题(需进一步讨论)
- 是否引入 canary 发布对连接池耗尽的快速检测?(下次架构评审讨论)
- staging 环境是否配置足够的连接压测负载?(@infra 评估)
- 与 epic / 工单互链;复盘会议结论与评论引用同一 ID。
- 设复查日期:短期修复与长期结构性改进分栏。
- 模板底部保留「未决问题」列表,防止口头结论丢失。
复盘会议 Facilitation 指南:
# 复盘会议引导规则
## 角色分工
- 主持人(Facilitator):控制节奏,确保讨论聚焦系统而非个人
- 记录人(Scribe):实时记录时间线、根因、行动项
- 技术 Lead:补充技术细节,不主导结论
- 所有参与者:对事不对人,鼓励诚实表达
## 会议结构(60min 为例)
- 0-5min: 主持人声明"无指责"基调与会议目标
- 5-15min: 共同确认时间线(不辩论,只补充)
- 15-30min: 影响评估与数据确认
- 30-45min: 五问法走完根因链(主持人控制深度)
- 45-58min: 起草行动项,每条确认 owner 与截止日
- 58-60min: 总结,约定复盘文档发布时间
## 禁止用语(主持人介入)
- "是你的错" / "你不应该" → 改为"该流程/工具如何改进"
- "总是这样" / "从来不" → 基于本次事实,不泛化
- "很简单,就是..." → 避免事后诸葛亮效应
五问链草稿器
填写现象与连续五个「为什么」,生成可粘贴进复盘稿的 Markdown 片段;用于 war room 后快速整理,再与证据交叉核对。
空行会自动跳过;生成后请用日志与变更记录验证每一层,避免臆造链条。可与上方「无指责原则」对照:措辞描述机制失效,不指向个人道德评判。
---
name: incident-postmortem
description: 从时间线与日志起草无指责复盘稿
model: claude-sonnet-4-5
---
# 复盘文档必含章节
sections:
- 摘要(时间窗口、影响用户比例、是否数据损坏)
- 事故等级(P0/P1/P2/P3 定义与本次判定)
- 时间线(UTC,含部署/配置变更节点)
- 影响评估(SLI 数据、用户/交易比例)
- 根因分析(直接原因 + 五问链 + 系统因素)
- 行动项(SMART 格式:owner/due/验收标准/工单)
- 未决问题
# 无指责写作规则
blameless_rules:
- 描述机制失效,不指向个人过失
- 人为操作 → 分析培训/工具/检查单缺口
- 行动项 owner 推进改进,非问责
# 五问法要求
five_whys:
- 每问附可核查证据(日志/配置/变更记录)
- 第五问落到可改项(监控/流程/文档)
- 避免循环论证和同义反复