路线图

09 On-Call 值班

星辉 2026-07-02 阅读 5 min 876 字 路线图
09 On-Call 值班 封面

概述#

On-call 是 SRE 工作中最直接影响工程师生活质量的部分。Google SRE Book 里有明确约束:SRE 的 on-call 工作量不能超过总时间的 25%。这不是福利,是工程要求——超了就说明告警治理、自动化、责任共担出了问题。

On-call 的本质不是"被人叫醒处理告警",而是"系统在非工作时间仍有可靠的人工兜底"。一个健康的 on-call 体系,应该让值班人能在被叫醒时高效处置、能在不被叫醒时安心睡觉、能在轮值结束后真正恢复。

本章从轮值制度设计到交接 SOP 到心理负荷管理,建立一套可持续的值班体系。大量实践经验来自 On-Call 轮值管理实战。

一、轮值制度设计#

三种主流轮值方式#

方式描述优点缺点
每周轮值周一~周日 7 天交接少,节奏统一周末剥夺感大
每日轮值24 小时一轮恢复快交接频繁(每次交接都是风险点)
工作日+周末分开工作日一人,周末另一人最人性化需要更多人手
白天+夜晚分开(follow-the-sun)跨时区轮值无夜间告警需要多地办公室

推荐方案:工作日 + 周末分开值班。周末值班给 1.5 倍补偿(调休或薪酬)。实测团队满意度最高。

团队规模与频率#

团队规模每人年 on-call 周数体感
4 人13 周疲惫(不建议)
5-6 人8-10 周有压力但可承受
7-8 人6-7 周较健康(最佳区间
9+ 人< 6 周脱手严重,不熟悉系统

最佳区间是 6-8 人。4 人以下建议和隔壁团队合并。9 人以上建议拆成两个 rotation——人太多导致每个人轮值间隔过长,对系统生疏。

补偿机制#

On-call 必须有显性补偿:

情景补偿
工作日 on-call1 天调休/班次
周末 on-call2 天调休/班次
夜间被叫醒(22:00-8:00)额外 0.5 天调休
处理 SEV-1/2 超过 2 小时计入加班

调休关键:允许在下一个 sprint 灵活消化,不能强制"当天补休"——否则 on-call 后的白天不休息也得干活,等于没补。

补偿不是福利,是工程要求。没有补偿的 on-call 不可持续——工程师会在 1-2 年内离职,带走所有系统知识。Google 的数据:on-call 补偿到位的团队,工程师平均在职时间 4.2 年;没有补偿的团队,平均 1.8 年。

不补偿的代价#

一个真实案例(来自 On-Call 实战文章):

一位很敬重的工程师在离职面谈里说:「我离职不是因为工资,也不是因为项目。是因为连续三个月每周被深夜 4 点叫醒,我老婆说再这样下去她要带孩子回娘家。我没法继续了。」

这位工程师离职后,团队失去了一个对系统最熟悉的人,bus factor 从 2 降到 1。后续 6 个月里发生了 3 次本来他能避免的事故——这就是不补偿的真实代价。

二、响应时间分级#

告警分级与响应 SLA#

级别响应要求(Ack)处理要求通道
P0 Critical5 分钟内立即响应,15 分钟 mitigation电话 + 钉钉
P1 Warning15 分钟内1 小时内开始处理钉钉
P2 Info下个工作日排期处理工单

Ack ≠ 处理完成。Ack 只是"我看到了,开始响应"。如果值班人 5 分钟不 ack,系统应自动升级。

为什么 Ack 和处理要分开#

事故响应有几个关键时间点:

  • TTD(Time to Detect):从故障发生到告警触发
  • TTA(Time to Acknowledge):从告警触发到值班人确认
  • TTM(Time to Mitigate):从 ack 到服务恢复
  • TTR(Time to Resolve):从告警到事故完全关闭
text
故障发生 ─── TTD ─── 告警 ─── TTA ─── Ack ─── TTM ─── Mitigated ─── TTR ─── Resolved

Ack 单独衡量是因为它反映"值班人是否可靠"。TTA 过长通常不是技术问题,是值班制度问题——值班人睡着了、手机静音了、网络断了。

升级链(Escalation Policy)#

text
Level 1 (0~5min)  : primary on-call
Level 2 (5~10min) : secondary on-call
Level 3 (10~15min): team lead
Level 4 (15+min)  : IMOC / manager on duty

关键规则:

  • primary 5 分钟不 ack,自动升级到 secondary
  • secondary 只在 primary 失联时顶上,不每个告警都叫两个人
  • 升级到 team lead 不是惩罚 primary,是流程的一部分
  • 升级不等于替代,primary 依然负责事故
  • 3 层足够,再多让 primary 产生依赖心理

Secondary 的设计#

  • 不会被每个告警打扰,只在 primary 未 ack 时
  • 可以比 primary 更低资历(如 L3 工程师配 L5 secondary)
  • 周期和 primary 错开一周,避免两人同时疲劳
  • secondary 也要被调度,但负担比 primary 小

不要让一个人扛#

最差的做法是"只有一个人被 page"。任何 SEV-2 以上,primary 应该主动拉 secondary 上线,不要死撑。明确告诉每个 on-call:你觉得扛不住就叫人,这不是软弱,是流程

三、交接 SOP#

交接是 on-call 最常被忽视的环节。糟糕的交接让新 on-call 的第一小时在猜谜

交接清单模板#

text
## On-Call Handoff: <from> -> <to>

### 日期
2026-07-01

### 待处理事项
- [ ] incident-2026-06-28-payment-api 还未写 postmortem
- [ ] 上周 OrderAPI_p99 告警调整的 Grafana dashboard
- [ ] ticket #1234 跟踪 MySQL SSL 证书续签

### 未解的根因
- Redis client 偶尔报 ETIMEDOUT(已压制,未定位)
- node-exporter 指标抖动,暂时放弃告警

### 环境变更
- 2026-06-30 Istio 从 1.21 升到 1.22
- 周四下午有一个新业务上线,sentinel 配额已预留

### 风险提醒
- MySQL 主库 SSL 证书 2026-07-05 过期,有 ticket #1234 跟进
- cert-manager 最近有异常重启,未定位

### Runbook 最近更新
- payment-api 的 rollback 步骤更新,新增 cache flush
- OrderAPI 的告警阈值调整说明

交接流程#

  • 交接会议 15 分钟,轮换日上午做
  • 值班人员一对一过文档
  • 所有内容归档到团队 wiki
  • 交接文档模板标准化,不允许"自由发挥"

交接的常见问题#

  • 口头交接没记录:3 天后双方都忘了说过什么
  • 只说事没说背景:新 on-call 知道"Redis 有问题"但不知道"已经排查到哪一步"
  • 风险提醒遗漏:证书快过期这种定时炸弹没说,新 on-call 完全不知道
  • Runbook 更新没同步:老 on-call 改了 runbook 但没告诉新 on-call,处理时还在用旧步骤

四、心理负荷管理#

On-call 最大的问题往往不是技术,是心理——焦虑、怕出错、怕被追责。

建立心理安全#

  1. 显性 Blameless 文化:事故响应群追究的不是"谁做的",而是"怎么修复和防止再发"
  2. 公开承认 on-call 辛苦:管理层在会议上说"我知道最近告警多,辛苦你们"比任何补偿都有效
  3. 允许说"我不会":on-call 不是全能工程师,遇到不会的事应该升级
  4. 事故后关怀:经历大事故后值班人应有一天 recovery time,可以什么都不做
  5. On-call 表现不和绩效挂钩:处理得好不加分,处理不好不扣分——只看"是否按流程响应"

第 5 条争议最大。有人说"处理得好为什么不奖励"。答案是:on-call 是 team sport,个人英雄主义反而会让团队依赖个别人,长期看是负债。奖励个人会激励"独揽"行为,破坏团队协作。

告警疲劳度量#

不只是感觉,要数据:

promql
# 每班次告警数
sum by(oncall_user) (increase(alertmanager_notifications_total{receiver="pager"}[7d]))

# 夜间告警占比
sum(increase(alertmanager_notifications_total{hour=~"22|23|0|1|2|3|4|5"}[30d]))
/ sum(increase(alertmanager_notifications_total[30d]))

# MTTA
avg(pd_incident_ack_time_seconds)

# 告警真阳率
count_over_time(incident_true_positive[30d])
/ count_over_time(incident_total[30d])

健康指标参考:

  • 每班次 page 告警:< 5 次
  • 夜间告警比例:< 10%
  • MTTA:< 5 分钟
  • 真阳率:> 70%

On-Call 问卷调查(每季度)#

  1. 过去一个月你被夜间叫醒多少次?
  2. 1-10 分,你的 on-call 疲劳度?(1=轻松,10=崩溃)
  3. 最让你疲劳的三个告警是什么?
  4. 有没有告警你根本不知道怎么处理?
  5. Runbook 有没有漏洞?
  6. 你觉得当前轮值规则公平吗?
  7. 有没有什么事你一直想做但 on-call 吃掉了所有精力?

疲劳度 > 6 分时必须启动告警治理(见 Ch08),而不是让值班人继续硬扛。让疲劳度数据报给管理层——这比任何 PPT 都能说明问题。

心理负荷的隐性影响#

on-call 的心理负荷不只在"被叫醒"那一刻,还在"等待被叫醒"的状态:

  • 周末不敢远离手机
  • 晚上不敢深度睡眠
  • 不敢安排长时间活动(看电影、出游)
  • 持续的"会有告警"的焦虑

这种"待命焦虑"会持续消耗心力,即使没有被叫醒。长期下来导致:

  • 睡眠质量下降
  • 注意力分散
  • 创造力下降(没法做深度工程)
  • 家庭关系紧张

治理方法:

  • 告警治理(最根本,减少告警数量)
  • Secondary 兜底(primary 知道"我失联也有人接")
  • 明确响应时间(5 分钟 ack,不是"立刻接电话")
  • 心理健康支持(EAP 服务)

五、新人培养路径#

新同事加入 on-call rotation 不应该直接上岗:

text
Shadow 2 周         → 作为 observer 参与,不做操作,只观察
Shadowed 2 周       → 作为 primary 响应,资深工程师 shadow 随时接管
独立 + backup 2 周  → 独立处理,backup 随叫随到
完全独立            → 加入轮值表

总共 6 周。时间长看起来慢,实际极大降低了新人的焦虑和误操作风险。

Shadow 阶段的细节#

  • 跟着 primary 一起被叫醒,一起处理
  • 不做任何操作,只观察
  • 每次告警后和 primary 一起 review:为什么这样处理?
  • 阅读 5-10 份历史 postmortem

Shadowed primary 阶段#

  • 作为 primary 接告警
  • 资深工程师在群里 shadow,随时准备接管
  • 操作前必须经 shadow 确认
  • 每次告警后 review:哪些操作是对的,哪些可以更好

独立 + backup 阶段#

  • 独立处理告警
  • backup 知道你在值班,可以求助
  • 复杂事故(SEV-1/2)必须拉 backup
  • 这阶段主要建立"独立决策"的信心

不要让新人独立扛 SEV-1#

新人独立 on-call 后的 3 个月内,SEV-1 事故必须有资深工程师协助。新人在高压下容易做错决策——这不是能力问题,是经验问题。

六、On-Call 工具栈#

告警分发#

  • Alertmanager:开源,路由/分组/抑制/静默
  • PagerDuty:商业,排班/升级/事件管理
  • Grafana OnCall:开源 + 商业,和 Grafana 生态集成好
  • OpsGenie:Atlassian 出品,和 Jira 集成

排班管理#

  • PagerDuty / OpsGenie:原生排班功能
  • 自研轮值表:Google Calendar / 钉钉机器人
  • Grafana OnCall:开源排班

事件管理#

  • incident.io / FireHydrant / Rootly:专业事件管理平台
  • 自研 bot:500 行 Python 处理告警 routing + 值班查询 + 交接 reminder

工具选型建议#

  • 小团队(< 10 人):Alertmanager + 自研轮值表就够
  • 中团队(10-50 人):Alertmanager + Grafana OnCall 或 PagerDuty
  • 大团队(50+ 人):必须用专业工具(PagerDuty / incident.io)

关键经验:不要一开始就上专业工具。先用 Confluence + 钉钉频道跑通流程,跑半年再决定是否买专业工具。专业工具主要省 20% 的操作,但 80% 的价值在你的流程和模板。

七、常见反模式#

反模式问题修正
一个人长期独揽表面"他最懂",实际是组织脆弱性强制轮值,bus factor > 1
告警越多越好以为覆盖全,实际噪音压死信号告警审计,砍到个位数/周
primary+secondary 都响应浪费两人时间secondary 只在 primary 失联时顶上
on-call 完全不补偿涸泽而渔调休或加班费
升级链越来越长primary 产生依赖心理3 层足够
把 on-call 当新人培训新人扛不住会崩溃先 shadow 再独立(6 周路径)
交接走流程不走心15 分钟会议变成 5 分钟念清单一对一过文档,问答必答
告警 group 设得过大合并 5 个独立告警成一条,丢失信号group_by 谨慎设置
runbook 过时没人更新改代码不改 runbook,下次值班人惨runbook 和代码同 PR
on-call 期间不能做其他事太奢侈,小告警可以穿插处理区分"待命"和"专注处理"

八、On-Call 改革的实际案例#

来自 On-Call 实战文章的改革前后对比:

维度改革前改革后
团队规模7 人8 人
每周告警28 次6 次
夜间告警比例29%8%
每人年 on-call 周数7.46.5
每人年被叫醒次数594
告警真阳率38%78%
on-call 疲劳度(问卷)7.2/103.8/10
季度主动离职20

改革具体做了什么:

  1. 加 1 人到 rotation
  2. 告警清理(4 周专项)
  3. 工作日 / 周末拆开
  4. 交接 SOP 固化
  5. 夜间告警 escalation 补偿
  6. 每季度 toil survey
  7. team lead 每月 1:1 关注 on-call 状态

没有一项是"神奇技术",都是工程化的细节。

九、给管理层的话#

如果你是 engineering manager 或 director,记住一件事:on-call 不是团队的副产品,是核心交付能力。你对 on-call 的投入应该和对线上质量的投入成正比。具体:

  1. 把 on-call 质量指标(告警数、夜间比例、疲劳度)放进你的 monthly report
  2. 给团队一个明确的"on-call 优化"时间预算,每季度至少 5% 的工时
  3. 当 on-call 疲劳度高于 6 分时,把新 feature 优先级往后推
  4. 一个工程师离职时主动问"是不是 on-call 的原因"
  5. 给 on-call 值班人显性致谢,无论是所有人会议还是团队频道

这些不是"软技能",是让工程团队可持续的硬工程。

实战要点#

  1. 量化 on-call 质量:告警数、夜间比例、疲劳度必须变成数字,不能靠"感觉这周有点忙"。
  2. 告警审计是 on-call 治理的核心(见 Ch08 详细方法)。先砍噪音,再谈轮值优化。
  3. 补偿机制写在制度里,不靠口头承诺。口头承诺的补偿在人员变动后会失效。
  4. 交接文档必须存在。一个团队如果靠口头交接,on-call 质量不可能稳定。
  5. 新人培养走 6 周路径,不要让新人直接上岗。
  6. 心理安全比技术能力更重要——一个不敢升级的初级 on-call 比一个能力差的 on-call 危险得多。
  7. 管理层必须参与 on-call 治理——这不是"团队内部事务",是组织可靠性能力的一部分。
  8. 每季度做 toil survey,让数据说话,不要等问题爆发才处理。

小结#

On-call 最能暴露一个团队是靠工程还是靠英雄主义在扛。可持续的 on-call = 合理的轮值制度 + 持续的告警治理 + 显性的心理支持 + 规范化的交接流程。

判断一个团队 on-call 是否健康,看三件事:每周 page 告警 < 5 次、季度疲劳度 < 5 分、新人有 6 周培养路径。三件事都做到是健康体系;只做到一两件是"在改进中";一件都没做,on-call 就是"靠人扛"的不可持续状态。

下一章讲事件管理——on-call 接收到告警后的系统化响应。