📝 第28课:事后复盘

核心概念

事后复盘(Post-Mortem):从故障中学习

无责备文化是SRE基石。复盘的目标不是追责,而是找到根因、改进系统、防止再发。

复盘会议流程

1. 回顾时间线(5-10分钟)
2. 识别根因(5Why分析法)
3. 讨论改进项(SMART原则)
4. 分配责任人和截止日期
5. 跟踪改进项完成

关键原则:
✅ 对事不对人 ✅ 所有人安全发言 ✅ 关注系统改进
❌ 不找替罪羊 ❌ 不隐瞒问题

命令实操

1. Post-Mortem模板 ✅

Post-Mortem模板
cat > postmortem-template.md << 'EOF'
# Post-Mortem: [事件ID]

## 基本信息
| 项目 | 内容 |
|------|------|
| 事件ID | INC-20260519-001 |
| 发生时间 | 2026-05-19 14:30 |
| 持续时间 | 45分钟 |
| 影响范围 | 30%用户无法下单 |
| 严重级别 | P1 |

## 时间线
| 时间 | 事件 |
|------|------|
| 14:30 | 监控告警:订单服务错误率>5% |
| 14:32 | On-Call确认问题 |
| 14:35 | 发现14:00部署的新版本有Bug |
| 14:38 | 决定回滚到v2.0 |
| 14:45 | 回滚完成 |
| 15:00 | 错误率恢复正常 |

## 根因分析(5Why)
1. 为什么订单错误率升高?→ 订单服务返回500
2. 为什么返回500?→ 数据库查询超时
3. 为什么查询超时?→ 新增的排序索引未创建
4. 为什么索引未创建?→ 迁移脚本在CI中被跳过
5. 为什么被跳过?→ CI配置的MIGRATE_SKIP=true未在prod环境移除

## 改进项
| # | 改进项 | 负责人 | 截止日期 | 优先级 |
|---|--------|--------|----------|--------|
| 1 | CI/CD区分环境变量配置 | Bob | 05/22 | P1 |
| 2 | 部署前自动验证DB迁移 | Carol | 05/25 | P1 |
| 3 | 添加DB查询超时监控 | Dave | 05/23 | P2 |
| 4 | 回滚演练纳入培训 | Alice | 05/30 | P2 |
EOF

2. 故障时间线自动生成 ✅

时间线生成
#!/bin/bash
# timeline-generator.sh
START_TIME="${1:?Start time (ISO8601)}"

echo "# Timeline"
echo "| 时间 | 来源 | 事件 |"
echo "|------|------|------|"

# K8s事件
kubectl get events -A --sort-by='.lastTimestamp' \
    --field-selector "lastTimestamp>=$START_TIME" \
    -o json | jq -r '.items[] | "| \(.lastTimestamp[11:16]) | K8s | \(.message) |"'

# Prometheus告警
curl -s 'http://prometheus:9090/api/v1/alerts' | \
    jq -r '.data.alerts[] | "| \(.activeAt[11:16]) | Alert | \(.labels.alertname) (\(.labels.severity)) |"'

# 部署历史
kubectl rollout history deployment/myapp | tail -10

# Git log
git log --since="$START_TIME" --oneline --format="| %h | Git | %s |" 

3. 改进项跟踪(GitHub Issues) ✅

改进项跟踪
#!/bin/bash
REPO="myorg/devops"
INCIDENT="INC-20260519-001"

declare -A ITEMS=(
  ["CI/CD区分环境变量配置"]="P1 @bob 05/22"
  ["部署前自动验证DB迁移"]="P1 @carol 05/25"
  ["添加DB查询超时监控"]="P2 @dave 05/23"
)

for title in "${!ITEMS[@]}"; do
    meta="${ITEMS[$title]}"
    gh issue create --repo "$REPO" \
        --title "[$INCIDENT] $title" \
        --body "来源: $INCIDENT Post-Mortem\n${meta}" \
        --label "postmortem-action-item"
done

架构图

事后复盘(Post-Mortem):从故障中学习架构

故障发生 → 应急处置 → 事件关闭 → Post-Mortem(48h内完成)
                              │
              ┌───────────────┼───────────────┐
              ▼               ▼               ▼
        根因分析         改进项定义        知识沉淀
        (5Why)          (SMART)          (Wiki/Runbook)
              └───────────────┼───────────────┘
                              ▼
                    ┌─────────────────┐
                    │  改进项跟踪      │
                    │  GitHub Issues  │
                    │  P1两周内完成   │
                    └─────────────────┘

故障排查

❌ 改进项长期未关闭

排查
gh issue list --label postmortem-action-item --state open --repo myorg/devops
# 周报:P1超过2周未关闭的项
gh issue list --label P1 --label postmortem-action-item --state open --repo myorg/devops \
    --json number,title,createdAt --jq '.[] | select((now - .createdAt | floor / 86400) > 14)'
💡 复盘黄金法则:48小时内完成、对事不对人、5Why深挖根因、P1改进项2周内关闭。

🏆 成就解锁:复盘专家!

掌握Post-Mortem模板、5Why根因分析、改进项跟踪——从故障中学习是成长的阶梯

📝 5Why根因分析模板

层级问题答案
Why 1为什么出现症状?直接原因
Why 2为什么发生直接原因?过程原因
Why 3为什么存在过程问题?系统性原因
Why 4为什么系统设计如此?架构原因
Why 5根本原因是什么?根因(修复此处)→
💡 复盘关键:对事不对人、5Why深挖根因、每个改进项必须有责任人和截止日期、P1改进项2周内完成。

🔧 改进项跟踪自动化

GitHub跟踪
# 创建改进项+设置提醒
create_action_item() {
    local title="$1"
    local priority="$2"
    local assignee="$3"
    local due="$4"
    
    gh issue create --repo myorg/devops \
        --title "[$INCIDENT] $title" \
        --body "来源: $INCIDENT Post-Mortem\n优先级: $priority\n截止: $due" \
        --assignee "$assignee" \
        --label "postmortem-action-item,$priority"
}

# 批量创建
create_action_item "CI/CD区分环境变量" "P1" "bob" "2026-05-22"
create_action_item "部署前自动验证DB迁移" "P1" "carol" "2026-05-25"
create_action_item "添加DB查询超时监控" "P2" "dave" "2026-05-23"

# 周报:未关闭的改进项
gh issue list --label postmortem-action-item \
    --state open --repo myorg/devops \
    --json number,title,createdAt,labels \
    --jq '.[] | "#\(.number) \(.title) [\(.labels[].name | select(startswith("P")))] \(.createdAt[:10])"'

📝 复盘检查清单

检查项要求完成?
时间线完整精确到分钟的事件记录
5Why根因分析至少5层深挖
无责备没有"某某操作失误"表述
改进项SMART具体+可衡量+有期限
责任人明确每项有唯一负责人
P1项2周内关闭跟踪机制就位
知识沉淀更新Runbook/Wiki
💡 复盘黄金法则:48小时内完成、所有人安全发言、对事不对人、改进项必须有截止日期。
⚠️ 学习建议:每课内容都需要在实验环境中实际操作验证,只有动手才能真正掌握。建议搭建自己的实验环境反复练习。

课前准备

课后巩固

进阶方向

📝 本课知识图谱

知识域核心技能验证方式
核心概念理解原理和架构能用自己的话解释
命令实操熟练使用相关工具能独立完成操作
故障排查定位和解决问题能在模拟故障中恢复
最佳实践遵循生产级标准能设计可靠方案
💡 持续学习:技术领域更新快,关注官方博客、GitHub Release、社区动态,保持知识新鲜度。