On-Call 体系与值班机制
一句话:On-Call 不是”轮到你你就得接电话”,而是一套分轮值守 + 告警分级 + 升级策略 + Runbook 支撑的工程化体系——保证故障有人接、接得住、能升级。
On-Call 体系全景
graph TD
ALERT[告警触发] --> ROUTE[告警路由<br/>按服务/严重程度]
ROUTE --> P1[Primary On-Call<br/>一线值班]
P1 -->|Ack| HANDLE[处理告警]
P1 -->|未 Ack 超时| ESCALATE1[升级到 Secondary]
ESCALATE1 -->|未 Ack| ESCALATE2[升级到 Manager]
ESCALATE2 -->|未 Ack| ESCALATE3[全员 Call]
HANDLE --> RUNBOOK[参考 Runbook]
RUNBOOK --> RESOLVE[恢复]
值班轮换设计
轮换模式
| 模式 | 周期 | 优点 | 缺点 | 适用 |
|---|
| Primary/Secondary | 1 周轮换 | 有备份、压力可接受 | 连续 1 周疲劳 | 中小团队 |
| 三级轮换 | 1 周轮换 | P→S→Manager 层层升级 | 需要更多人 | 大团队 |
| Follow-the-Sun | 按时区 | 无夜间值班 | 需要跨国团队 | 全球团队 |
| 24/7 单人 | 3-5 天轮换 | 简单 | 疲劳严重 | 不推荐 |
推荐轮换方案
推荐方案: Primary + Secondary 双人轮换
轮换周期: 1 周(周一 10:00 交接)
休息恢复: 轮换后至少 1 天不值班
人员要求:
Primary: 能独立处理 SEV2,知道何时升级
Secondary: 能处理 SEV1,作为 Primary 的备份
排班规则:
- 连续值班不超过 1 周
- 值班后至少 1 天恢复
- 节假日提前排班 + 补偿
- 每个 Primary 必须有 Secondary 备份
排班表示例
from datetime import datetime, timedelta
from dataclasses import dataclass
@dataclass
class OnCallShift:
start: datetime
end: datetime
primary: str
secondary: str
manager: str
def generate_schedule(team: list[str], weeks: int, start_date: datetime) -> list:
"""生成 On-Call 排班表"""
schedule = []
n = len(team)
for i in range(weeks):
week_start = start_date + timedelta(weeks=i)
week_end = week_start + timedelta(days=7)
primary = team[i % n]
secondary = team[(i + 1) % n]
manager = team[(i + 2) % n] # 经理也轮换
schedule.append(OnCallShift(
start=week_start,
end=week_end,
primary=primary,
secondary=secondary,
manager=manager,
))
return schedule
# 示例
team = ["张三", "李四", "王五", "赵六"]
schedule = generate_schedule(team, 4, datetime(2026, 8, 3))
for s in schedule:
print(f"{s.start.date()} ~ {s.end.date()}: P={s.primary} S={s.secondary} M={s.manager}")
告警分级与路由
告警分级
| 级别 | 触发条件 | 通知方式 | 响应 SLA | 升级 |
|---|
| Page | SEV1/SEV2 | 电话 + IM 推送 | 5/15 min | 10 min 未 Ack → Secondary |
| Ticket | SEV3 | 工单系统 | 工作时间 | 24h 未处理 → Primary |
| Info | SEV4 | 日志/看板 | 无 | 无 |
Alertmanager 路由配置
route:
receiver: default
group_by: ['service', 'severity']
group_wait: 10s
group_interval: 5m
repeat_interval: 4h
routes:
# SEV1: 电话通知 Primary
- match:
severity: critical
receiver: phone-primary
group_wait: 0s
repeat_interval: 30m
routes:
# 10 分钟未 Ack 升级到 Secondary
- match:
acknowledged: 'false'
receiver: phone-secondary
continue: true
# SEV2: IM 通知 Primary
- match:
severity: warning
receiver: im-primary
group_wait: 30s
repeat_interval: 2h
receivers:
- name: phone-primary
webhook_configs:
- url: 'https://pagerduty.com/integration/xxx'
send_resolved: true
- name: phone-secondary
webhook_configs:
- url: 'https://pagerduty.com/integration/yyy'
send_resolved: true
- name: im-primary
webhook_configs:
- url: 'https://open.feishu.cn/open-apis/bot/v2/hook/xxx'
send_resolved: true
Runbook 体系
Runbook 是什么
Runbook = 标准化操作手册——告诉 On-Call “这个告警来了该做什么”。
Runbook vs 文档:
文档 = 知识(为什么这样做)
Runbook = 操作(具体做什么)
Runbook 特点:
- 按"告警名"索引(告警来了直接查对应 Runbook)
- 步骤化(Step 1 → Step 2 → Step 3)
- 含命令(可以直接复制执行)
- 含决策点("如果 X 则 A,否则 B")
- 含升级条件("到这里还不行就升级")
Runbook 模板
# Runbook: [告警名称]
## 告警信息
- 告警名: HighMemoryUsage
- 严重程度: warning
- 服务: api-gateway
- 触发条件: 内存使用率 > 85%
## 快速诊断
1. 检查内存趋势: `kubectl top pods -n production | grep api-gateway`
2. 检查是否 OOM: `kubectl get events -n production | grep OOMKilled`
3. 检查近期变更: `argocd app history api-gateway`
## 处理步骤
### 如果是新版本导致的内存泄漏
1. 回滚: `argocd app rollback api-gateway <previous-revision>`
2. 确认恢复: `curl http://api-gateway:8080/health`
3. 通知: 在故障群发消息 "已回滚 api-gateway 到 vX.X.X"
### 如果是流量增长导致
1. 扩容: `kubectl scale deployment api-gateway -n production --replicas=8`
2. 确认: `kubectl get pods -n production | grep api-gateway`
### 如果是 OOM
1. 临时增加内存: `kubectl patch deployment api-gateway -n production ...`
2. 排查内存泄漏(需开发介入)
## 升级条件
- 回滚后 5 分钟未恢复 → 升级到 Secondary
- 确认是代码 Bug → 拉入开发负责人
- 影响范围扩大 → 升级为 SEV1
On-Call 交接清单
## On-Call 交接清单
### 交接时需要同步的信息
- [ ] 本周处理的告警汇总(数量/类型/未解决)
- [ ] 正在跟进的 Action Items 进度
- [ ] 已知风险(即将到期的容量/计划变更)
- [ ] 特殊情况(假期/大促/灰度发布进行中)
- [ ] Runbook 需要更新的地方
### 交接方式
- 口头交接 + 文档同步
- 交接时间: 周一 10:00(避开早晚高峰)
On-Call 福利与健康
On-Call 健康原则:
1. 保证休息: 值班后至少 1 天恢复
2. 公平轮换: 不让同一个人长期值班
3. 补偿机制: 值班补贴 + 调休
4. 减少噪音: 告警降噪,只 Page 真正紧急的
5. 工具支撑: Runbook 完善,减少"不知所措"
6. 心理支持: SEV1 后给恢复时间,复盘不追责
常见问题 / 坑点
| 问题 | 原因 | 解决方案 |
|---|
| 半夜被叫醒处理 SEV3 | 告警分级不当 | SEV3 不 Page,走工单 |
| 升级链太长 | Primary 不 Ack | 设短超时(5-10 min),快速升级 |
| Runbook 过时 | 告警改了但 Runbook 没更新 | 告警和 Runbook 绑定,改告警必须改 Runbook |
| 新人不敢值班 | 怕处理不了 | 影子值班(Shadow On-Call)+ 完善 Runbook |
| 值班疲劳 | 连续多周值班 | 强制轮换休息 + 减少告警噪音 |
关联知识
状态