名称: 运行手册-事件响应 描述: 用于创建事件响应程序和值班手册。涵盖事件管理、通信协议和事后文档。 允许的工具:
- 读取
- 写入
- 编辑
- Bash
- Grep
- Glob
运行手册 - 事件响应
创建有效的事件响应程序,以处理生产事件和值班场景。
事件响应框架
事件严重性级别
SEV-1 (严重)
- 服务完全中断
- 数据丢失或安全漏洞
- 重大客户影响 (>50% 的用户)
- 响应时间: 立即
- 升级: 呼叫值班 + 经理
SEV-2 (高)
- 部分服务降级
- 影响大量用户 (10-50%)
- 性能问题 (>50% 慢)
- 响应时间: 15分钟内
- 升级: 呼叫值班
SEV-3 (中)
- 轻微降级
- 影响少量用户 (<10%)
- 非关键功能损坏
- 响应时间: 1小时内
- 升级: 值班人员在业务时间内处理
SEV-4 (低)
- 外观问题
- 内部工具受影响
- 无客户影响
- 响应时间: 下一个工作日
- 升级: 创建工单,不呼叫
事件响应模板
# 事件响应: [警报/问题名称]
**严重性:** SEV-1/SEV-2/SEV-3/SEV-4
**响应时间:** 立即 / 15分钟 / 1小时 / 次日
**负责人:** 值班工程师
## 事件检测
**此运行手册由以下触发:**
- PagerDuty 警报: `api_error_rate_high`
- 客户在 #support 中报告
- 监控仪表盘显示异常
## 初始响应 (前5分钟)
### 1. 确认与评估
```bash
# 检查当前状态
curl https://api.example.com/health
kubectl get pods -n production
确定严重性:
- 所有请求失败 → SEV-1
- 部分失败 → SEV-2
- 性能降级 → SEV-3
2. 通知利益相关者
SEV-1:
- 创建 Slack 事件频道:
/incident create SEV-1 API 中断 - 呼叫工程经理
- 通知客户成功团队
SEV-2:
- 在 #incidents 频道发布
- 标记值班团队
SEV-3:
- 在 #engineering 频道发布
- 不需要呼叫
3. 开始事件时间线
创建事件文档 (复制模板):
事件: API 中断
开始时间: 2025-01-15 14:30 UTC
严重性: SEV-1
时间线:
14:30 - 警报触发
14:31 - 值班确认
14:32 - 评估为 SEV-1
14:33 - 创建事件频道
立即缓解 (前15分钟)
目标: 止血,恢复服务
快速缓解选项
选项 A: 回滚最近部署
# 检查最近部署
kubectl rollout history deployment/api-server
# 回滚如果部署 < 30 分钟前
kubectl rollout undo deployment/api-server
使用时机: 部署与事件开始时间一致。
选项 B: 扩展规模
# 增加副本数
kubectl scale deployment/api-server --replicas=20
使用时机: 高流量,资源耗尽。
选项 C: 重启服务
# 重启 Pod
kubectl rollout restart deployment/api-server
使用时机: 内存泄漏,连接池问题。
选项 D: 启用断路器
# 禁用失败的外部服务调用
kubectl set env deployment/api-server FEATURE_EXTERNAL_API=false
使用时机: 第三方服务降级。
通信协议
更新频率
SEV-1: 每10分钟 SEV-2: 每30分钟 SEV-3: 每小时
通信模板
**[14:45] 更新**
**状态:** 调查中
**影响:** API 返回 503 错误。约 75% 请求失败。
**已采取行动:**
- 回滚了 14:25 的部署
- 将 Pod 副本增加到 15
**下一步:**
- 监控回滚影响
- 调查数据库连接问题
**预计时间:** 未知
**客户影响:** 用户无法下单。
**临时解决方案:** 无。
状态更新
## 状态消息
**调查中:**
> 我们注意到 API 错误率升高。
> 正在调查根本原因。每10分钟更新。
**已识别:**
> 根本原因已识别: 数据库连接池耗尽。
> 正在实施修复。
**监控中:**
> 修复已部署。错误率下降。
> 监控30分钟后宣布解决。
**已解决:**
> 事件已解决。错误率恢复正常。
> 事后分析将跟进。
调查 (与缓解并行)
服务恢复期间,调查根本原因:
1. 收集证据
# 捕获日志前它们轮转
kubectl logs deployment/api-server > incident-logs.txt
# 快照指标
curl -H "Authorization: Bearer $DD_API_KEY" \
"https://api.datadoghq.com/api/v1/graph/snapshot?..." > metrics.png
# 数据库状态
psql -c "SELECT * FROM pg_stat_activity" > db-state.txt
2. 时间线重构
## 时间线
| 时间 | 事件 | 证据 |
|------|-------|----------|
| 14:20 | 部署开始 | GitHub Actions 日志 |
| 14:25 | 部署完成 | ArgoCD |
| 14:30 | 错误率飙升 | Datadog 警报 |
| 14:32 | 数据库连接满 | CloudWatch |
| 14:35 | 回滚启动 | kubectl history |
| 14:38 | 服务恢复 | Datadog 指标 |
3. 根本原因分析
## 根本原因
**直接原因:**
部署引入了用户端点中的 N+1 查询模式。
**促成因素:**
- 缺少 users.created_at 的数据库索引
- CI 中没有查询性能测试
- 数据库连接池太小,无法应对流量峰值
**为什么未发现:**
- 测试环境流量是生产的 10% 以下
- 负载测试未覆盖此端点
- 没有查询性能的警报
解决与验证
宣布事件解决
标准 (必须全部满足):
- [ ] 错误率 < 1% 持续30分钟
- [ ] 响应时间 p95 < 200ms
- [ ] 15分钟内无客户投诉
- [ ] 根本原因修复已部署 (不仅是缓解)
- [ ] 监控确认稳定
事后行动
## 立即 (1小时内)
- [ ] 发布解决方案更新到 #incidents
- [ ] 更新状态页面为 "运行中"
- [ ] 感谢响应者
- [ ] 关闭 PagerDuty 事件
## 短期 (24小时内)
- [ ] 创建事后分析工单
- [ ] 安排事后分析会议
- [ ] 提取行动项
- [ ] 用学习更新运行手册
## 长期 (1周内)
- [ ] 完成事后分析的行动项
- [ ] 添加监控/警报以防止复发
- [ ] 记录到事件数据库
事后分析模板
# 事后分析: API 中断 - 2025-01-15
**日期:** 2025-01-15
**持续时间:** 14:30 UTC - 14:45 UTC (15分钟)
**严重性:** SEV-1
**影响:** 75% 的 API 请求失败
**作者:** 值班工程师, 团队负责人
## 摘要
在 1月15日 14:30 UTC,我们的 API 经历了一次完全中断,影响了约 75% 的请求。事件持续了15分钟,由部署中引入的 N+1 查询触发的数据库连接池耗尽引起。
## 影响
**客户影响:**
- 约 1,500 用户无法完成购买
- 估计收入损失: $50,000
- 47 个支持工单提交
**内部影响:**
- 3 名工程师从其他工作中抽调
- 15 分钟完全中断
- 工程经理被呼叫
## 时间线 (所有时间 UTC)
**14:20** - 部署 #1234 合并并开始部署
**14:25** - 部署完成,新代码服务流量
**14:30** - 警报触发: `api_error_rate_high`
**14:31** - 值班工程师确认
**14:32** - 评估为 SEV-1,创建事件频道
**14:33** - 识别数据库连接池耗尽
**14:35** - 启动回滚到前一个版本
**14:38** - 回滚完成,错误率下降
**14:40** - 服务稳定,监控中
**14:45** - 宣布解决
## 根本原因
部署在 `/users/recent` 端点中引入了一个 N+1 查询。对于返回的每个用户,代码进行了额外的数据库查询以获取其个人资料图片 URL。随着 50 个并发请求,这导致 50 × 20 = 1,000 个数据库查询,耗尽了连接池 (配置为 100 个连接)。
**代码变更:**
```diff
- user.profile_picture_url # 查询中预加载
+ user.get_profile_picture() # 每个用户额外查询
促成因素
- 缺少索引:
users.created_at未索引,使基础查询变慢 - 连接池小: 100 个连接不足以应对流量峰值
- 无查询监控: 没有查询数量或持续时间的警报
- 负载测试不足: 测试环境只有生产流量的 10%
做得好
- ✅ 快速检测 (< 1 分钟从开始)
- ✅ 清晰的升级路径
- ✅ 回滚工作顺利
- ✅ 与利益相关者良好沟通
- ✅ 服务在15分钟内完全恢复
做得不好
- ❌ 代码审查未发现 N+1 查询
- ❌ 没有自动查询性能测试
- ❌ 警报触发但根本原因识别花了5分钟
- ❌ 错误峰值时无自动回滚
行动项
| 行动 | 负责人 | 截止日期 | 优先级 |
|---|---|---|---|
| 添加数据库索引到 users.created_at | Alice | 2025-01-16 | P0 |
| 增加连接池到 200 | Bob | 2025-01-16 | P0 |
| 添加查询性能测试到 CI | Charlie | 2025-01-20 | P1 |
| 实现错误峰值时的自动回滚 | Dave | 2025-01-30 | P1 |
| 创建 ORM 查询 linter 以检测 N+1 | Eve | 2025-02-15 | P2 |
学习
- 预防: 需要在代码审查中自动检测 N+1 查询
- 检测: 应基于数据库查询数量警报,而不仅是错误
- 缓解: 自动回滚可将平均修复时间减少5分钟以上
- 恢复: 回滚有效,保持为主要策略
附录
## 值班手册
```markdown
# 值班手册
## 值班前
**1周前:**
- [ ] 回顾近期事件
- [ ] 如果需要,更新值班运行手册
- [ ] 测试 PagerDuty 通知
**1天前:**
- [ ] 验证笔记本电脑就绪 (充电,VPN 工作)
- [ ] 测试所有系统访问
- [ ] 回顾当前系统状态
- [ ] 检查日历是否有冲突事件
## 值班期间
### 收到呼叫时
**1分钟内:**
1. 在 PagerDuty 确认警报
2. 检查警报详情了解严重性
3. 打开相关运行手册
**5分钟内:**
4. 评估严重性 (真的是 SEV-1?)
5. 如果 SEV-1/SEV-2,创建事件频道
6. 发布初始状态更新
### 升级决策树
收到呼叫
|
我能单独处理吗?
/ \
是 否
| |
处理它 升级
| |
已解决? 与团队合作
/ \ |
是 否 已解决?
| | |
关闭 需要帮助 是
\ |
\ 关闭
\ |
升级
### 交接程序
**值班结束清单:**
- [ ] 无活跃事件
- [ ] 状态文档更新
- [ ] 下一位值班确认交接
- [ ] 向下一值班简要介绍任何持续问题
**交接模板:**
嘿 @下一位值班! 正在进行值班交接。这是当前状态:
活跃问题: 无
需关注事项:
- 数据库 CPU 升高但稳定 (85%)
- 计划明天 10 AM 部署
近期事件:
- 昨天 SEV-2: 数据库慢查询 (已解决) 事后分析: [链接]
系统状态:
- 所有服务绿色
- 无即将进行的维护
如有疑问,请告诉我!
## 值班后
- [ ] 用新学习更新运行手册
- [ ] 完成事件的事后分析
- [ ] 为发现的问题提交错误工单
- [ ] 分享警报/运行手册反馈
反模式
不要恐慌
# 坏: 反应混乱
一切中断! 重启所有东西!
# 好: 冷静评估
服务降级。让我检查:
1. 实际影响是什么?
2. 什么时候开始的?
3. 最快的安全缓解是什么?
不要跳过沟通
# 坏: 沉默修复
*解决问题而不告诉任何人*
*将事件标记为已解决*
# 好: 定期更新
[14:30] 调查 API 错误
[14:40] 根本原因识别,部署修复
[14:45] 修复部署,监控中
[15:00] 服务稳定,事件解决
不要跳过后事分析
# 坏: 快速继续
已修复! 继续下一个任务。
# 好: 从事件中学习
- 记录发生了什么
- 识别行动项
- 防止复发
- 与团队分享学习
相关技能
- 运行手册结构: 组织事件响应程序
- 故障排除指南: 诊断事件期间的问题