事后分析:Postmortem最佳实践
事后分析:Postmortem最佳实践
什么是事后分析
事后分析(Postmortem)是在事故或故障发生后进行的系统性回顾,目的是找出根本原因、总结经验教训并制定改进措施。一个良好的事后分析文化能帮助团队从每次事故中学习。
事后分析原则
事后分析核心原则:
├── 1. 无指责文化 (Blameless)
├── 2. 聚焦系统改进
├── 3. 完整透明
├── 4. 可执行的行动项
└── 5. 及时完成
事后分析模板
完整模板
# 事后分析报告
## 事件概要
- **事件ID**: INC-2024-001
- **标题**: API服务数据库连接池耗尽导致服务不可用
- **事件等级**: P1 - 严重
- **发生时间**: 2024-01-15 14:00 (UTC+8)
- **发现时间**: 2024-01-15 14:05 (UTC+8)
- **恢复时间**: 2024-01-15 14:45 (UTC+8)
- **总持续时间**: 45分钟
## 影响范围
- **受影响服务**: API服务、Web应用、移动端
- **受影响用户**: 约50,000用户无法访问服务
- **业务影响**: 预计损失订单金额约¥100,000
- **SLA影响**: 消耗月度错误预算的34%
## 时间线
| 时间 (UTC+8) | 事件 |
|--------------|------|
| 14:00 | 流量突增,超过正常水平3倍 |
| 14:02 | 数据库连接池开始耗尽 |
| 14:05 | 监控告警触发,通知值班人员 |
| 14:08 | 值班人员开始排查 |
| 14:15 | 定位到数据库连接池问题 |
| 14:20 | 尝试重启API服务,未解决 |
| 14:25 | 手动增加数据库连接池大小 |
| 14:30 | 连接池扩容生效,服务开始恢复 |
| 14:40 | 所有服务恢复正常 |
| 14:45 | 确认问题完全解决 |
## 根本原因分析
### 直接原因
数据库连接池配置过小(默认10个连接),无法应对流量突增场景。
### 间接原因
1. 缺少连接池监控和告警
2. 流量增长预估不足
3. 缺少自动扩容机制
### 根本原因
系统设计时未充分考虑流量增长场景,缺少必要的容量规划和自动扩展能力。
## 响应评估
### 做得好的地方
1. 告警系统及时触发
2. 值班人员快速响应
3. 团队协作顺畅
### 需要改进的地方
1. 问题定位时间较长(10分钟)
2. 初始尝试的修复方案无效
3. 缺少自动化恢复能力
## 行动项
### 短期行动项(1周内)
- [ ] 增加数据库连接池监控指标
- [ ] 调整连接池告警阈值
- [ ] 更新运维手册
### 中期行动项(1个月内)
- [ ] 实现数据库连接池自动扩容
- [ ] 添加流量预测和告警
- [ ] 建立容量规划流程
### 长期行动项(3个月内)
- [ ] 设计流量自适应架构
- [ ] 建立完整的混沌工程实践
- [ ] 优化监控和告警体系
## 经验教训
1. **监控覆盖**: 关键指标必须有监控和告警
2. **容量规划**: 定期进行容量评估和规划
3. **自动化**: 关键恢复操作应该自动化
4. **文档更新**: 及时更新运维文档和流程
## 附件
- 事故时间线详细记录
- 监控图表截图
- 日志分析结果
无指责文化
语言规范
避免使用:
✗ "某某导致了事故"
✗ "谁犯了错误"
✗ "为什么没做好"
应该使用:
✓ "系统在X情况下出现了Y问题"
✓ "流程中缺少Z步骤"
✓ "我们需要改进X机制"
分析焦点
# 聚焦系统改进而非个人责任
focus:
system_factors:
- "监控覆盖不足"
- "自动化程度低"
- "文档不完整"
- "流程不清晰"
process_factors:
- "变更管理不严格"
- "测试覆盖不足"
- "审查流程缺失"
people_factors:
- "培训不足"
- "知识共享不够"
- "沟通渠道不畅"
数据收集
自动化数据收集
#!/bin/bash
# collect-incident-data.sh - 事故数据收集脚本
INCIDENT_ID=$1
TIME_START=$2
TIME_END=$3
OUTPUT_DIR="/tmp/incidents/$INCIDENT_ID"
mkdir -p $OUTPUT_DIR
# 1. 系统指标
echo "收集系统指标..."
curl -s "http://prometheus/api/v1/query_range?query=rate(http_requests_total[1m])&start=$TIME_START&end=$TIME_END&step=60" > $OUTPUT_DIR/http_requests.json
curl -s "http://prometheus/api/v1/query_range?query=histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[1m]))&start=$TIME_START&end=$TIME_END&step=60" > $OUTPUT_DIR/latency.json
# 2. 应用日志
echo "收集应用日志..."
kubectl logs -l app=api-server --since=$TIME_START --until=$TIME_END > $OUTPUT_DIR/app.log
# 3. 系统日志
echo "收集系统日志..."
journalctl --since="$TIME_START" --until="$TIME_END" > $OUTPUT_DIR/system.log
# 4. 事件信息
echo "收集事件信息..."
kubectl get events --all-namespaces --sort-by=.metadata.creationTimestamp > $OUTPUT_DIR/events.txt
# 5. 部署信息
echo "收集部署信息..."
kubectl get deployments -o yaml > $OUTPUT_DIR/deployments.yaml
echo "数据收集完成: $OUTPUT_DIR"
事后分析会议
会议议程
# 事后分析会议议程
agenda:
- topic: "事件概要"
duration: "5分钟"
presenter: "事故指挥官"
- topic: "时间线回顾"
duration: "10分钟"
presenter: "技术负责人"
- topic: "根本原因分析"
duration: "15分钟"
presenter: "技术团队"
- topic: "经验教训"
duration: "10分钟"
presenter: "全体参与者"
- topic: "行动项讨论"
duration: "15分钟"
presenter: "团队负责人"
- topic: "下一步计划"
duration: "5分钟"
presenter: "会议主持人"
会议最佳实践
# 事后分析会议指南
## 会前准备
- 收集完整的时间线数据
- 准备监控图表和日志
- 邀请所有相关人员
## 会议规则
- 保持无指责文化
- 每个人都有发言机会
- 聚焦事实和改进
- 避免情绪化讨论
## 会后跟进
- 记录所有行动项
- 分配负责人和截止日期
- 定期跟踪进展
- 更新运维文档
行动项管理
行动项跟踪
# action-items.yaml
action_items:
- id: "AI-001"
title: "增加数据库连接池监控"
priority: "high"
owner: "运维团队"
deadline: "2024-01-22"
status: "in_progress"
description: "在Prometheus中添加数据库连接池使用率监控"
- id: "AI-002"
title: "实现自动扩容"
priority: "medium"
owner: "架构团队"
deadline: "2024-02-15"
status: "todo"
description: "设计和实现数据库连接池自动扩容机制"
指标和度量
# 事后分析指标
# 1. 平均响应时间
# 2. 行动项完成率
# 3. 重复事故发生率
# 4. 团队满意度
# 计算行动项完成率
COMPLETED=$(grep -c "status: done" action-items.yaml)
TOTAL=$(grep -c "id:" action-items.yaml)
RATE=$(echo "scale=2; $COMPLETED / $TOTAL * 100" | bc)
echo "行动项完成率: ${RATE}%"
最佳实践
- 及时性: 事故后48小时内完成事后分析
- 无指责: 专注于系统改进而非个人责任
- 透明度: 分享完整的事后分析报告
- 可执行: 行动项要具体、可度量、有负责人
- 跟踪: 定期跟踪行动项进展
- 改进: 持续优化事后分析流程