事故响应:生产事件处理流程
事故响应框架
事故响应流程:
├── 1. 检测与告警 (Detection)
├── 2. 分类与优先级 (Triage)
├── 3. 响应与缓解 (Response)
├── 4. 恢复与验证 (Recovery)
└── 5. 事后分析 (Postmortem)
事故分级
# incident-severity.yaml
severity:
P1_Critical:
description: "核心业务完全中断"
response_time: "5分钟"
update_interval: "15分钟"
escalation: "立即通知CTO"
examples:
- "网站完全无法访问"
- "支付系统故障"
- "数据丢失"
P2_High:
description: "核心业务严重受损"
response_time: "15分钟"
update_interval: "30分钟"
escalation: "通知技术总监"
examples:
- "主要功能不可用"
- "性能严重下降"
- "部分用户受影响"
P3_Medium:
description: "业务功能部分受损"
response_time: "30分钟"
update_interval: "1小时"
escalation: "通知团队负责人"
examples:
- "非核心功能故障"
- "性能轻微下降"
- "少量用户受影响"
P4_Low:
description: "轻微问题或优化需求"
response_time: "4小时"
update_interval: "24小时"
escalation: "按正常流程处理"
examples:
- "UI显示问题"
- "非紧急优化"
值班机制
值班轮转配置
# oncall-config.yaml
oncall:
primary:
schedule: "weekly"
rotation:
- name: "Alice"
phone: "+86-138-xxxx-xxxx"
email: "alice@example.com"
slack: "@alice"
timezone: "Asia/Shanghai"
- name: "Bob"
phone: "+86-139-xxxx-xxxx"
email: "bob@example.com"
slack: "@bob"
timezone: "Asia/Shanghai"
secondary:
schedule: "weekly"
offset: 1 # 比primary晚一周
members:
- name: "Charlie"
phone: "+86-137-xxxx-xxxx"
email: "charlie@example.com"
escalation:
- after: "5m"
notify: "secondary_oncall"
- after: "15m"
notify: "team_lead"
- after: "30m"
notify: "engineering_director"
- after: "1h"
notify: "cto"
PagerDuty配置
# 使用PagerDuty API创建事故
curl -X POST https://api.pagerduty.com/incidents \
-H "Authorization: Token token=$PAGERDUTY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"incident": {
"type": "incident",
"title": "API服务响应超时",
"service": {
"id": "PXXXXXX",
"type": "service_reference"
},
"urgency": "high",
"body": {
"type": "incident_body",
"details": "API服务P99延迟超过5秒,影响用户访问"
},
"escalation_policy": {
"id": "PXXXXXX",
"type": "escalation_policy_reference"
}
}
}'
事故指挥系统
事故角色
# incident-roles.yaml
roles:
Incident_Commander:
responsibility: "整体指挥和决策"
tasks:
- "组建响应团队"
- "制定响应策略"
- "协调资源"
- "做出关键决策"
Communications_Lead:
responsibility: "内外部沟通"
tasks:
- "更新状态页面"
- "通知利益相关者"
- "准备沟通材料"
- "管理客户沟通"
Technical_Lead:
responsibility: "技术问题解决"
tasks:
- "诊断问题"
- "实施修复"
- "验证恢复"
- "编写技术文档`
Operations_Lead:
responsibility: "运维操作"
tasks:
- "执行变更"
- "监控系统"
- "收集日志"
- "备份数据"
事故沟通模板
# 事故沟通模板
## 初始通知
**标题**: [事故] 服务名称 - 问题描述
**时间**: YYYY-MM-DD HH:MM (UTC+8)
**影响**: 简要描述影响范围
## 状态更新
**时间**: YYYY-MM-DD HH:MM
**当前状态**: [调查中/修复中/已恢复]
**影响范围**: 受影响的服务和用户
**采取措施**: 已执行和计划执行的操作
**预计恢复时间**: 预计时间或"待评估"
## 恢复通知
**时间**: YYYY-MM-DD HH:MM
**恢复状态**: 问题已解决
**影响总结**: 影响时长和范围
**后续计划**: 事后分析安排
故障排查流程
快速诊断脚本
#!/bin/bash
# quick-diagnosis.sh - 快速诊断脚本
echo "=== 系统状态检查 ==="
echo "时间: $(date)"
# 1. 检查系统资源
echo -e "\n--- 系统资源 ---"
echo "CPU使用率:"
top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1
echo "内存使用:"
free -h | grep Mem | awk '{print "总计:", $2, "已用:", $3, "可用:", $4}'
echo "磁盘使用:"
df -h / | tail -1 | awk '{print "使用率:", $5}'
# 2. 检查网络
echo -e "\n--- 网络状态 ---"
echo "网络连接数:"
ss -s | grep "estab" | awk '{print $4}'
echo "网络接口流量:"
ifconfig eth0 | grep "RX packets" | awk '{print "接收:", $2, "bytes"}'
# 3. 检查服务状态
echo -e "\n--- 服务状态 ---"
systemctl is-active nginx && echo "Nginx: 运行中" || echo "Nginx: 停止"
systemctl is-active mysql && echo "MySQL: 运行中" || echo "MySQL: 停止"
# 4. 检查日志
echo -e "\n--- 最近错误日志 ---"
tail -n 20 /var/log/nginx/error.log 2>/dev/null || echo "无Nginx错误日志"
故障定位流程
# 故障定位步骤
# 1. 确认问题
curl -s -o /dev/null -w "%{http_code}" http://api/health
# 2. 查看日志
tail -f /var/log/app/error.log
# 3. 检查进程
ps aux | grep -E "(nginx|java|python)" | grep -v grep
# 4. 检查网络
netstat -tlnp | grep -E ":(80|443|8080)"
# 5. 检查连接
ss -s
ss -tnp | grep ":443"
# 6. 抓包分析
tcpdump -i eth0 -w capture.pcap port 443
恢复操作
自动化恢复脚本
#!/bin/bash
# incident-recovery.sh - 事故恢复脚本
SERVICE=$1
ACTION=$2
case $ACTION in
"restart")
echo "重启服务: $SERVICE"
systemctl restart $SERVICE
sleep 10
systemctl status $SERVICE
;;
"rollback")
echo "回滚服务: $SERVICE"
CURRENT_VERSION=$(kubectl get deployment $SERVICE -o jsonpath='{.spec.template.spec.containers[0].image}')
PREVIOUS_VERSION=$(echo $CURRENT_VERSION | sed 's/v[0-9]*/v&/' | sed 's/v\([0-9]*\)/\1-1/')
kubectl set image deployment/$SERVICE \
$SERVICE=$PREVIOUS_VERSION \
--record
kubectl rollout status deployment/$SERVICE
;;
"scale")
echo "扩容服务: $SERVICE"
CURRENT_REPLICAS=$(kubectl get deployment $SERVICE -o jsonpath='{.spec.replicas}')
NEW_REPLICAS=$((CURRENT_REPLICAS * 2))
kubectl scale deployment/$SERVICE --replicas=$NEW_REPLICAS
;;
"failover")
echo "故障转移: $SERVICE"
# 切换到备用节点
kubectl patch service $SERVICE -p '{"spec":{"selector":{"active":"false"}}}'
;;
esac
验证恢复
#!/bin/bash
# verify-recovery.sh - 验证恢复
SERVICE=$1
URL=$2
echo "验证服务恢复: $SERVICE"
# 1. 检查健康状态
for i in {1..10}; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" $URL)
if [ "$STATUS" = "200" ]; then
echo "健康检查通过 (第${i}次)"
else
echo "健康检查失败 (第${i}次): HTTP $STATUS"
sleep 5
fi
done
# 2. 检查错误率
ERROR_RATE=$(curl -s "http://prometheus/api/v1/query?query=rate(http_requests_total{code=~'5..'}[5m])" | jq -r '.data.result[0].value[1]')
echo "当前错误率: $ERROR_RATE"
# 3. 检查延迟
LATENCY=$(curl -s "http://prometheus/api/v1/query?query=histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))" | jq -r '.data.result[0].value[1]')
echo "P99延迟: ${LATENCY}秒"
事后分析
事后分析模板
# 事后分析报告
## 事件信息
- **事件ID**: INC-YYYY-NNN
- **事件等级**: P1/P2/P3/P4
- **发生时间**: YYYY-MM-DD HH:MM (UTC+8)
- **恢复时间**: YYYY-MM-DD HH:MM (UTC+8)
- **持续时间**: X小时X分钟
## 影响范围
- **受影响服务**: 列出服务
- **受影响用户**: 用户数量/百分比
- **业务影响**: 收入损失/用户影响
## 时间线
| 时间 | 事件 | 操作人 |
|------|------|--------|
| HH:MM | 事件发生 | 系统 |
| HH:MM | 告警触发 | 监控 |
| HH:MM | 开始响应 | 值班人员 |
| HH:MM | 问题定位 | 技术团队 |
| HH:MM | 执行修复 | 运维团队 |
| HH:MM | 系统恢复 | 验证通过 |
## 根本原因
详细描述事件的根本原因
## 修复措施
- 临时措施
- 长期措施
## 经验教训
- 做得好的地方
- 需要改进的地方
- 行动项
## 行动项
- [ ] 行动项1 - 负责人 - 截止日期
- [ ] 行动项2 - 负责人 - 截止日期
最佳实践
- 建立清晰的流程:定义明确的响应流程
- 定期演练:定期进行事故响应演练
- 工具自动化:使用工具自动化响应流程
- 文档化:记录所有事故和处理过程
- 持续改进:根据事后分析持续改进流程