跳到主要内容

运维篇 · 03 · 故障响应

本章目标

让团队在故障发生时有标准动作,不靠英雄主义。

一、故障分级

1.1 严重度(Severity)

级别定义例子
SEV-1核心业务完全不可用 / 数据丢失全站无法下单、订单数据错乱
SEV-2核心业务部分不可用 / 明显体验劣化登录偶尔失败、支付延迟 10s+
SEV-3非核心功能异常 / 部分用户受影响报表导出慢、某地区访问慢
SEV-4轻微问题 / 不影响业务文案错误、日志告警

1.2 响应时间 SLA

级别确认响应启动处置解决目标
SEV-15 分钟10 分钟1 小时
SEV-215 分钟30 分钟4 小时
SEV-31 小时4 小时24 小时
SEV-4下一工作日下一 Sprint按排期

1.3 影响面评估

故障发生时同时评估:

维度问题
用户范围所有 / 大部分 / 少数 / 单一
功能范围全站 / 核心流 / 边缘功能
时间范围持续 / 偶发 / 已恢复
数据影响无 / 读错误 / 写错误 / 丢失

二、故障响应组织

2.1 角色

          ┌─────────────┐
│ Incident │
│ Commander │ ← 指挥官,唯一决策人
│ (IC) │
└──────┬──────┘

┌────────────┼────────────┐
│ │ │
┌──────┐ ┌──────┐ ┌──────┐
│Tech │ │Comms │ │Ops │
│Lead │ │Lead │ │Lead │
└──────┘ └──────┘ └──────┘
技术指挥 沟通 执行

2.2 职责

角色职责
IC(Incident Commander)统筹全局,不动手,只决策
Tech Lead技术诊断,协调工程师
Comms Lead对内/对外沟通,写更新公告
Ops Lead执行回滚/降级/扩容等操作

2.3 关键规则

  • IC 不动手:动手的人无法兼顾全局
  • IC 唯一:只有一个人拍板,避免多头决策
  • 角色轮值:每次故障不一定是同一批人
  • 明示角色:故障群里每个人自报角色

三、故障处置流程

发现 ──► 确认 ──► 分级 ──► 通报 ──► 诊断 ──► 处置 ──► 验证 ──► 通报结束 ──► 复盘
(监控/用户) (IC 决定) (并行) (立即生效) (24h 内)

3.1 发现阶段(0-5 分钟)

  • 来源:监控告警 / 用户反馈 / 值班发现
  • 值班人立即确认是否真故障
  • 不是故障 → 关闭告警,更新 runbook
  • 是故障 → 进入确认阶段

3.2 确认阶段(5-10 分钟)

  • 判断严重度(SEV-1/2/3/4)
  • 指定 IC(通常值班 leader)
  • 创建故障群 / 故障单
  • 通知相关方

3.3 通报阶段(并行,持续)

对内通报(故障群)

【故障】SEV-1 订单服务不可用

📍 影响: 全站无法下单
⏰ 开始: 2026-04-15 10:30
👤 IC: @alice
🔍 Tech: @bob
📢 Comms: @charlie

【当前进展】
- 10:30 监控告警
- 10:32 确认故障
- 10:35 开始诊断

对外通报(状态页 / 客服)

⚠️ 订单功能异常中

我们已发现订单系统异常,工程师正在紧急处理。
预计影响时间: 待定
服务恢复后我们会第一时间通知。

状态页: https://status.example.com

通报节奏:SEV-1 每 15 分钟一更,SEV-2 每 30 分钟一更。

3.4 诊断阶段

黄金 5 问

  1. 什么变了?

    • 最近的发布?配置变更?数据变更?
    • 流量变化?依赖变化?
  2. 什么还能工作?

    • 缩小范围:哪些服务好的、哪些坏的
  3. 什么在报错?

    • 查日志、查监控、查链路追踪
  4. 已知的类似问题?

    • 翻 runbook、翻历史故障
  5. 如果不是代码问题,是什么?

    • 基础设施?网络?第三方?

3.5 处置阶段

优先恢复业务,而不是定位根因

处置动作适合
回滚到上一版本最近有发布
扩容负载过高
切换流量单一节点/区域问题
降级非核心功能核心服务还能跑,但吃资源
重启服务内存泄漏、连接池耗尽
限流流量异常

处置期的纪律

  • 每次操作前先说明
  • 操作后立即观察
  • 不要多人同时乱改
  • 保留现场证据(日志快照、监控截图)

3.6 验证阶段

  • 监控指标已恢复正常
  • 核心功能已验证
  • 测试用户已回访
  • 持续观察 30 分钟以上
  • 无回潮迹象

3.7 结束通报

【故障结束】SEV-1 订单服务已恢复

⏰ 开始: 2026-04-15 10:30
⏰ 恢复: 2026-04-15 11:45
⏱️ 持续: 1 小时 15 分钟

【处置过程】
- 10:30 告警
- 10:45 确认为新版本 bug
- 11:15 回滚
- 11:30 服务恢复
- 11:45 持续观察后确认稳定

【临时措施】
已回滚到 v1.2.0,修复后再重新发布 v1.2.1

【后续】
- 故障复盘会议: 明天 14:00
- 复盘报告: 48h 内产出

四、Runbook(故障处置手册)

4.1 什么是 Runbook

每个高频故障场景都应该有一份处置手册,包含:

  • 故障现象
  • 快速定位步骤
  • 处置方案
  • 验证方法

4.2 Runbook 模板

# Runbook: 订单服务错误率飙升

## 现象
- 告警: API error rate > 1%
- 用户反馈: 下单失败

## 快速定位(5 分钟内)

### 1. 看发布
```bash
kubectl rollout history deployment/order-service

最近 1 小时有发布? → 考虑回滚

2. 看依赖

# 看下游调用
curl http://order-service/health/deps

某依赖不可用? → 降级该依赖

3. 看资源

kubectl top pods -l app=order-service

某 pod CPU/内存爆? → 扩容/重启

处置方案

方案 A: 回滚(首选)

kubectl rollout undo deployment/order-service

方案 B: 扩容

kubectl scale deployment/order-service --replicas=10

方案 C: 降级

修改配置中心:order.payment.enabled=false

验证

# 观察指标
curl http://grafana/api/.../error-rate

常见根因

  • 代码 Bug(最近有发布)
  • 下游依赖故障(支付服务挂)
  • 数据库慢查询(看 slow log)

### 4.3 Runbook 的管理

- 放在代码仓库里(与代码一起版本管理)
- 每个 Runbook 有 owner
- 每季度 review 一次
- 每次新故障后更新对应 Runbook

## 五、故障值班制度

### 5.1 值班模式

**三班倒**(大团队):
- 白班 / 晚班 / 夜班
- 每班 8 小时,有 handoff

**主备制**(中小团队):
- 主值班:主要响应
- 备值班:主值班处理不过来时 backup

**轮值**(小团队):
- 每周一人 primary,全天 on-call

### 5.2 值班职责

- **接告警**(必须 5 分钟内响应)
- **初步诊断**
- **决定升级**(自己处理不了,叫 IC)
- **更新 runbook**
- **值班交接**(写 handoff 日志)

### 5.3 值班工具

- 告警呼叫(PagerDuty / Opsgenie / 自研)
- 手机 on-call
- VPN / 跳板机权限
- Runbook 库访问
- 故障群快捷入口

### 5.4 值班友好度

- **无告警睡觉**:值班不代表无事不响应,告警要靠谱
- **handoff 规范**:交接清单、待办事项
- **值班补偿**:补休 / 补贴
- **疲劳管理**:避免连续多周值班

## 六、故障演练

### 6.1 演练的价值

- 发现 runbook 漏洞
- 训练团队反应
- 验证故障处置流程
- 减少真故障时的慌乱

### 6.2 演练类型

| 类型 | 说明 | 频率 |
|------|------|------|
| **桌面演练** | 讨论"假设 X 故障了怎么办" | 月度 |
| **断网演练** | 真实切断某个依赖 | 季度 |
| **混沌工程** | 自动注入故障(Chaos Mesh) | 持续 |
| **值班演练** | 模拟半夜告警 | 季度 |

### 6.3 演练注意事项

- **演练前通知**(非混沌工程的情况)
- **有回滚按钮**(万一演练失控)
- **演练日志**(记录发现的问题)
- **事后更新 runbook**

## 七、配套资源

- [01 发布 SOP](./01-release-sop.md)
- [02 监控与告警](./02-monitoring.md)
- [04 故障复盘](./04-postmortem.md)
- [05 AI 辅助运维](./05-ai-assistance.md)