跳过正文
SRE 故障管理全生命周期:从响应到复盘

SRE 故障管理全生命周期:从响应到复盘

·754 字·4 分钟·
目录
SRE 可靠性工程师路径 - 这篇文章属于一个选集。
§ : 本文

2024 年有一次 P1 故障,我们花了 40 分钟才把所有相关人拉进会议,而故障本身 20 分钟就修好了。那 40 分钟里,销售团队在群里问进度,CEO 在私信我,技术 VP 在问根因,我一边排查一边回消息,最后谁都没说清楚。

这次故障之后,我们系统性地建立了故障管理流程。核心洞察是:技术处理和协调沟通必须并行,但必须由不同的人承担

故障定级标准
#

定级是故障管理的起点,决定了后续的响应力度和沟通范围。我们用影响面和严重程度两个维度定级:

定级矩阵
#

级别用户影响营收影响响应时效通知范围
P1核心功能完全不可用(> 10% 用户受影响)直接损失 > 10k/小时立即响应,全员CTO、VP、全团队
P2核心功能部分降级,有可用替代路径间接影响,难以量化30 分钟内团队负责人、SRE
P3非核心功能异常,有 workaround无明显影响工作时间内值班工程师

P1 的判断原则:宁可误报,不能漏报。不确定是 P1 还是 P2 时,先按 P1 处理,升级成本远低于漏报代价。

快速定级决策树
#

告警触发
├── 支付/登录/核心业务接口不可用?→ P1
├── 错误率 > 5% 且持续 > 2min?→ P1
├── 数据库/消息队列等基础设施完全不可用?→ P1
├── 错误率 1%-5% 或部分功能降级?→ P2
├── 单用户投诉 / 边缘功能异常?→ P3
└── 不确定?→ 先 P1,处理中降级

Incident Commander:为什么不能一人兼三职
#

故障响应中有三个核心角色,必须分清楚:

Incident Commander(IC):故障整体协调人,负责推进响应节奏、协调资源、决定升级时机。IC 不一定技术最强,但必须有决策权和全局视角。IC 的职责是确保事情在推进,而不是自己去干。

技术负责人(Tech Lead):实际排查和修复故障的工程师,专注在技术操作,不承担对外沟通职责。

沟通负责人(Comms):向外部(用户、客户、管理层)和内部(其他团队)输出状态更新,屏蔽技术人员被打扰。

为什么不能一人兼三职?

工程师的大脑在压力下无法高效切换任务。排查故障需要深度思考,任何打断都会造成"上下文切换成本"。我们测算过,一次 Slack 消息打断需要约 8 分钟才能重新进入专注状态。P1 故障的前 30 分钟,技术负责人被打断一次,可能就是多 15 分钟的恢复时间。

小团队怎么办?

人手不够时,IC 可以兼 Comms,但绝对不能兼 Tech Lead。IC 的核心价值是保证技术人员能专心干活。

响应 Checklist:前 5 分钟
#

P1 故障的前 5 分钟是混乱的高峰期,Checklist 能防止遗漏。

IC 执行:

  • 确认告警是真实的(不是监控自身问题)
  • 初步评估影响范围(哪些用户、哪些功能)
  • 在 #incident 频道发起故障线程
  • 确认技术负责人已接手
  • 确认沟通负责人已就位
  • 评估是否需要立即通知外部用户

技术负责人执行:

  • 打开监控面板,确认故障范围
  • 检查是否有近期变更(部署、配置、流量变化)
  • 开始定界(见下节)

沟通负责人执行:

  • 向管理层发送初始通知(仅确认在处理,不报根因)
  • 如有 Status Page,更新状态为 Investigating
  • 准备用户通知草稿(等 IC 确认后发出)

15 分钟定界框架
#

定界(Scoping)是找到故障边界:什么是坏的,什么是好的,问题出在哪一层。目标是 15 分钟内完成初步定界,给技术团队和管理层都一个方向。

按层级从外到内排查:

第一层:网络层(2 分钟)
#

# 外部连通性
curl -w "%{http_code} %{time_total}s" -o /dev/null https://api.example.com/health

# DNS 解析
dig api.example.com +short

# 负载均衡健康检查(以 AWS ALB 为例)
aws elbv2 describe-target-health --target-group-arn arn:aws:... --region us-west-2

# K8s Service / Ingress 状态
kubectl get ingress -A
kubectl get svc -n production

如果外部请求直接超时,且 DNS 正常,问题可能在 LB 或 Ingress 层。

第二层:应用层(3 分钟)
#

# Pod 状态总览
kubectl get pod -n production -o wide | grep -v Running

# 最近的重启情况
kubectl get pod -n production -o custom-columns=NAME:.metadata.name,RESTARTS:.status.containerStatuses[0].restartCount | sort -k2 -n -r | head -10

# 快速查看错误日志
kubectl logs -n production deploy/api-service --tail=50 | grep -i "error\|panic\|fatal"

# 检查 HPA 状态(是否在扩缩容中)
kubectl get hpa -n production

第三层:数据层(3 分钟)
#

# 数据库连接测试(从应用 Pod 内部)
kubectl exec -n production deploy/api-service -- nc -zv mysql-master.data 3306

# 检查连接池状态(以 Go 为例,需应用暴露 /debug/vars 或 metrics)
curl http://api-service:9090/metrics | grep db_pool

# Redis 连通性
kubectl exec -n production deploy/api-service -- redis-cli -h redis-master ping

# 检查慢查询(MySQL)
kubectl exec -n data deploy/mysql -- mysql -u root -p'password' -e "SHOW PROCESSLIST;" | grep -v Sleep

第四层:基础设施层(3 分钟)
#

# 节点状态
kubectl get node -o wide

# 节点资源压力
kubectl top node

# 存储 PVC 状态
kubectl get pvc -A | grep -v Bound

# 最近发生的事件
kubectl get events -A --sort-by=.lastTimestamp | tail -30

定界结论模板

[定界结论] 2026-04-12 03:25
问题层:数据层(MySQL 连接池耗尽)
正常层:网络层、应用层(Pod 运行正常)
影响范围:所有需要写入的 API(/api/v1/payment, /api/v1/order)
已排除:网络问题、部署变更、K8s 基础设施
下一步:扩大连接池限制或重启数据库

沟通模板
#

内部状态更新(每 15 分钟一次)
#

[P1 更新] 2026-04-12 03:30 | 进行中 | 已持续 18 分钟

现状:MySQL 连接池耗尽,支付接口全部返回 500
进展:DBA 已介入,正在评估连接池扩容方案
预计恢复:30 分钟内(预计 04:00 前)
临时缓解:已关闭非必要写操作,降低数据库压力

下次更新:15 分钟后或状态有变化时

外部用户通知
#

原则:简单、诚实、有时间预期,不解释技术细节。

我们正在处理一个影响支付功能的问题。部分用户在完成支付时可能遇到错误。
我们的团队已在处理中,预计在 [时间] 前恢复正常。感谢您的耐心等待。

不要写由于数据库连接池参数配置不当导致...(用户不需要知道这些,而且写出来后面可能变)

Post-Mortem 模板
#

Post-Mortem 的价值在于系统性改进,不是追责。Blameless 文化的落地要点:描述发生了什么,不描述谁做了什么错误决定

# Post-Mortem:支付服务不可用事件
**日期**:2026-04-12
**级别**:P1
**持续时间**:23 分钟(03:12 - 03:35)
**撰写人**:[姓名]
**状态**:待审核

## 影响
- 支付接口 100% 不可用,持续 23 分钟
- 受影响用户:约 2,400 次支付请求失败
- 估计营收影响:约 ¥85,000

## 时间线

| 时间 | 事件 |
|------|------|
| 03:10 | MySQL 连接池达到上限(100/100),新请求开始排队 |
| 03:12 | 错误率超过 5%,PagerDuty 告警触发 |
| 03:13 | 值班工程师 Acknowledge |
| 03:15 | 定位到数据库连接问题 |
| 03:17 | 支付服务切换到只读降级模式 |
| 03:19 | DBA on-call 介入 |
| 03:28 | MySQL 连接池配置更新,Pod 重启 |
| 03:33 | 错误率回落到 < 0.1% |
| 03:35 | 宣布故障解除,支付恢复正常 |

## 根因

MySQL 连接池上限设置为 100,上个 Sprint 支付服务扩容到 8 个 Pod,每 Pod 最多 15 个连接,峰值需求为 120 个连接,超出数据库允许的上限。

流量高峰(凌晨 3 点的定时任务批量处理)触发了连接池耗尽。

## 贡献因素

1. 扩容时没有同步更新数据库连接池配置
2. 数据库连接池使用量没有告警(只有 Pod 数量告警)
3. 没有针对连接池接近上限的 Runbook

## 改进措施

| # | 措施 | 类型 | 责任人 | 截止日期 |
|---|------|------|-------|---------|
| 1 | 为 MySQL 连接池使用率添加告警(> 80% 告警,> 90% P1)| 监控 | @张三 | 2026-04-19 |
| 2 | 扩容 Checklist 中增加数据库连接池容量评估 | 流程 | @李四 | 2026-04-19 |
| 3 | 支付服务 Runbook 增加连接池耗尽处理步骤 | 文档 | @王五 | 2026-04-16 |
| 4 | 将连接池配置外部化(通过 Nacos 管理),支持不重启更新 | 工程 | @赵六 | 2026-05-01 |

## 做得好的地方
- 定界速度快,3 分钟确认数据库层问题
- 降级方案(只读模式)执行有效,阻止了问题继续扩大
- DBA on-call 响应及时

## 经验教训
扩容不只是加 Pod,需要系统性评估所有依赖资源的容量。

Post-Mortem Review 会议
#

写完不开会等于白写。Post-Mortem 需要在故障后 48-72 小时内完成 Review:

  • 参会人:IC、技术负责人、相关团队 Lead
  • 时长:30-60 分钟
  • 目标:确认根因无异议、Action Items 有 owner 和截止日期
  • 禁止:追责性言论(“为什么你没有…")

改进追踪:让 Action Items 真正落地
#

Post-Mortem 变成走过场的最大原因:Action Items 没有 SMART 属性,没人跟进。

SMART 写法对比

糟糕的写法SMART 写法
改进监控2026-04-19 前,@张三 为 MySQL 连接池添加 80% 使用率告警,在 Grafana payment 面板新增连接池面板
优化扩容流程2026-04-19 前,@李四 在服务扩容 Runbook 中增加数据库连接容量评估步骤,并在下次扩容时验证

我们用 Jira 管理 Action Items,Post-Mortem 的每一条改进措施都创建为 story,挂在对应 Sprint。每周 SRE 会议固定 5 分钟 review 未关闭的 Post-Mortem action items。

30 天不关闭的 Action Item,会进入工程健康度报告,在季度复盘中说明原因或重新排期。

真实案例:数据库连接池耗尽的完整 IM 过程
#

这就是上面 Post-Mortem 对应的真实故障处理记录。几个关键时刻值得复盘:

为什么 23 分钟就解决了?

  1. IC(我)没有参与排查,专注协调:通知 DBA、每 5 分钟在频道更新状态、屏蔽管理层的直接询问
  2. 技术负责人有 Runbook,数据库连接排查步骤清晰,3 分钟就定界到数据层
  3. 降级方案(只读模式)是预案,不是临时想出来的,执行很快

如果没有这套流程会怎样?

参照之前的经验:一个人又排查又沟通,大概率 1 小时内不会结束,期间管理层和产品会不断问进度,排查时间线会更长。

常见陷阱
#

陷阱 1:把 Post-Mortem 变成审判

“谁让你部署的”、“当时为什么没想到”——这类问题会让工程师下次故障时不愿意如实记录。Blameless 不是免责,是把注意力放在系统问题而不是个人失误上。

陷阱 2:故障解决了就算了,不写 Post-Mortem

P2 以上故障,无论多忙,都必须写 Post-Mortem。我们的最低要求:时间线 + 根因 + 至少 1 条 Action Item。其他部分可以简化,但这三样不能省。

陷阱 3:IC 参与技术排查

IC 一旦"下水"开始自己排查,就没人做协调了。技术 Lead 需要 IC 拍板决策时,IC 参与决策;技术细节排查,IC 不参与。

陷阱 4:定界没有时限

“我们再看看”——这句话在故障处理中是危险的。每个排查方向给固定时间(3-5 分钟),时间到没有结论就换方向或升级。大多数故障的根因在 15 分钟内能确定层次,不能定界的情况应该触发升级。

故障处理能力是练出来的。从定级开始,到 IC 轮换、Post-Mortem Review,每次故障都是一次往前迭代的机会——真的不要浪费。

Wenzhuo Huang
作者
Wenzhuo Huang
搞运维的工程师,写代码的运维人。专注 Kubernetes、AWS、GitOps 与基础设施可靠性。这个博客既是我的技术笔记本,也是我踩过的坑的受害者档案。
SRE 可靠性工程师路径 - 这篇文章属于一个选集。
§ : 本文

相关文章

SRE 核心理念:从运维思维到可靠性工程

·679 字·4 分钟
SRE 不是给运维换了个更好听的名字。它是一套用软件工程思维解决可靠性问题的方法论。本文从 Error Budget 切入,覆盖 SLI/SLO 制定、Toil 识别、On-call 设计、故障复盘文化,以及从传统运维转型 SRE 的实际路径。

多集群 Kubernetes 运维:跨集群管理与统一可观测

·1202 字·6 分钟
从单集群到多集群,运维复杂度不是线性增加,而是指数级。这篇文章总结了我们管理跨地域、跨环境多套 K8s 集群的实际经验:如何用 ArgoCD ApplicationSet 统一部署、如何用 Thanos 聚合多集群指标、以及一次真实的跨集群迁移过程。

Kubernetes 集群升级策略:零停机升级的完整实践指南

·855 字·5 分钟
K8s 集群升级听起来简单,实际操作中坑很多:API 弃用导致的 Helm 失败、Admission Webhook 拦截升级流量、PDB 配置不当导致服务中断。这篇文章从真实的升级经验出发,给出一套可复用的零停机升级方案。