On-Call 最佳实践
值班制度、告警管理、轮值策略与On-Call素养。
1. 从”急诊室值班”说起
1.1 On-Call 到底是什么
想象医院里的急诊室:病人在任何时间都可能被送来,所以急诊医生必须轮流值班——这周是你,深夜 2 点也可能被叫起来;你不在的时候,会有另一位医生接替你。值班医生的职责不是”治好所有病”,而是”在病人到来时,第一时间稳住局面,该止血的止血、该转科的转科”。
On-Call(在线值班)在软件行业里的含义一模一样:软件系统 7×24 小时运行,出问题的时间不分白天黑夜。团队需要安排工程师轮流值班,在系统出故障时第一时间响应、止血、恢复。
On-Call 的核心定义:
On-Call 是工程师轮流承担”系统故障第一响应人”的制度:告警响了,值班工程师负责确认问题、评估影响、止损恢复,并决定是否需要升级。
1.2 谁需要 On-Call
不是所有团队都需要 7×24 值班。判断标准很简单:你的系统在”非工作时间”出问题,会造成什么后果?
- 内部工具(只有员工用,白天用):工作日值班即可
- 对外服务(用户随时在用):需要 7×24 值班
- 交易/金融/医疗系统(出事故后果严重):必须 7×24,且升级路径要非常严密
关键认知:On-Call 不是”运维团队的事”,而是”研发团队的事”。业界有一条原则叫”谁开发谁运维”(You build it, you run it):让写代码的人负责自己代码的线上运行。因为只有写代码的人才最清楚”这个系统哪里容易出问题、出问题该怎么排查”。让完全不了解代码的人值班,等于让不懂这台机器的机修工去修飞机。
2. 值班轮换的设计:让制度可持续
On-Call 制度最大的敌人是不可持续。值班工程师要忍受半夜被叫醒、周末被打断、持续的精神压力。如果制度设计不合理,团队很快就会倦怠、流失。以下是设计健康轮值的核心规则(数据来自 Google SRE 实践与业界调研):
2.1 规则一:每轮值班至少 6 人
Google SRE 的经验是:每个轮值小组至少要 6 人。为什么?
- 6 人轮值,每个人大约每 6 周才值一次班,中间有充分的恢复期
- 如果只有 4 人,意味着每 4 周就轮到一次,一年 13 次值班,睡眠、社交、健康全部被侵蚀
- 少于 6 人时,一旦有人请假/生病,剩下的几个人被迫高频轮值,直接崩溃
如果团队不足 6 人怎么办? 不要硬上 24×7 轮值,改为:
- 与兄弟团队合作(follow-the-sun,按区域接力值班)
- 只在业务高峰时段值班(triage-only hours),非高峰段告警自动转工单、次日处理
2.2 规则二:主备双人制
永远不要只让一个人独扛值班。 标准配置是”主值班 + 备值班”:
| 角色 | 确认窗口 | 升级触发 |
|---|---|---|
| 主值班(Primary) | 5 分钟内确认 | 未确认 → 自动升级到备值班 |
| 备值班(Secondary) | 10 分钟内确认 | 未确认 → 升级到技术负责人 |
| 技术负责人(EM) | 15 分钟内确认 | 未确认 → 升级到更高级别 |
为什么必须双人?因为主值班可能正在睡觉、在飞机上、在开会——人的不可达性比想象中高得多。双人制让”确认失败”的概率大幅下降。
2.3 规则三:每班告警上限 2 次
这是 Google SRE 公开书里最重要的数字之一:一个值班班次(12 小时)内,被真实告警打扰的次数上限是 2 次。
如果值班期间被叫醒超过 2 次,说明系统有问题,而不是值班工程师”不行”:可能是告警太吵(噪音太多)、系统太脆弱(频繁故障)、或者两者兼有。
把这个数字当成”健康红线”来监控:如果连续两个月的平均值超过 2 次/班,就要把它当作系统问题来治理(告警收敛、稳定性建设),而不是让值班工程师硬扛。
2.4 规则四:每次交接都要有仪式
交接是轮值制度里最容易被忽视、也最昂贵的环节。值班交接不只是一句话”我下班了你上”,而是一次结构化的信息传递。
交接至少覆盖四件事:
- 进行中的事故:当前有没有未处理完的故障?进展如何?
- 持续关注项:有哪些”已知的坑”?比如某个告警最近总是误报、某个依赖下周要发新版
- 本周变更:这周部署了什么?下一个值班者需要知道哪些变更可能引起问题
- Runbook 更新:这周发现哪些排查手册不准确?有没有补充?
代价:跳过交接的团队,会反复”重新发现”同一个问题——上一个班次发现的线索,下一个班次完全不知道,然后从头排查。
2.5 规则五:补偿必须明确
值班是额外付出,团队必须有明确的补偿机制(三选一,必须选一个):
- 补休:晚上 10 点后或周末被叫起的时间,兑换成带薪补休,两周内休掉
- 固定津贴:值班期间每周固定补贴(比如 300-800 美元/周,无论是否被叫醒)
- 混合制:少量固定补贴 + 每次实际响应额外补贴
最差的制度是”你是月薪制,自己消化”——把值班成本转嫁给工程师的健康,最终体现在离职率上。行业调研数据:没有明确值班补偿的团队,资深工程师离职率是对照组的 2.4 倍。
3. 告警管理:让告警”少而准”
告警是 On-Call 的”触发源”。告警管理的目标不是”覆盖所有异常”,而是”每一次告警都值得叫醒一个人”。
3.1 告警疲劳:On-Call 的头号杀手
行业现状(多家观测平台 2025-2026 年的调研数据):一个监控体系一周可以产生上千条告警,其中真正需要立即行动的只占约 3%。其余全是:
- 41% 自行恢复(等工程师打开电脑时,指标已经恢复正常了)
- 18% 重复告警(同一个问题的多个监控各自报警)
- 22% 没有 Runbook(工程师接到告警后不知道该怎么排查)
当告警大多数是噪音时,人会本能地”无视提醒”——就像”狼来了”故事里的村民。这就是告警疲劳,它的可怕之处在于:当真正的 P0 事故发生时,值班工程师的第一反应也是”又是误报吧”,宝贵的黄金响应时间被浪费在”确认告警是否真实”上。
3.2 好告警的标准:基于用户体验,而非机器指标
设计告警时,问自己一个问题:这个告警响起来时,用户正在经历什么?
错误示例:监控到”某台服务器 CPU 超过 90%“就告警。但 CPU 高并不等于用户受影响——可能只是批处理任务在跑,用户完全无感。
正确示例:监控到”过去 5 分钟,用户请求的错误率超过 5%“才告警。告警应该描述用户体验的劣化,而不是底层指标的变化。 底层指标只是用户问题的”代理信号”,而且是嘈杂的代理信号。
业界把需要持续监控的信号总结为四大黄金信号(The Four Golden Signals):
| 信号 | 含义 | 示例 |
|---|---|---|
| 延迟 Latency | 请求响应有多快 | P95 响应时间 < 500ms |
| 流量 Traffic | 系统承受的负载 | 每秒请求数、并发连接数 |
| 错误 Errors | 请求失败的比例 | 5xx 占比、显式错误码 |
| 饱和度 Saturation | 系统还能承受多少 | CPU/内存/队列水位 |
告警原则:优先围绕”错误率和延迟”这类用户体验信号设计告警,而不是围绕 CPU、内存这类机器指标。
3.3 SLO 错误预算告警:告警的新范式
2026 年主流团队已经抛弃”指标超过阈值就告警”的老办法,改用基于 SLO(服务等级目标)的告警。
先理解三个概念:
- SLI(Service Level Indicator,服务等级指标):实际测量的指标。如”30 天内成功请求占比 99.7%”
- SLO(Service Level Objective,服务等级目标):团队设定的内部目标。如”30 天内可用性 ≥ 99.5%”
- 错误预算(Error Budget):SLO 允许的”失败额度”。SLO 99.9% 意味着每月允许失败 43.2 分钟
基于错误预算的告警逻辑:不是”指标坏了就告警”,而是”错误预算消耗速度过快才告警”。
举例:SLO 是”月度可用性 99.9%“,对应每月错误预算 43 分钟。
- 如果当前错误率会在 24 小时内烧光整个月预算 → 立即告警(P1,叫醒人)
- 如果当前错误率会在一周内烧光预算 → 创建工单,工作时间处理
- 如果消耗速度正常 → 不告警
这种告警方式自动过滤了”短暂抖动但总体健康”的情况,从根本上消灭了大量噪音告警。
3.4 告警分级与升级路径
每个告警必须有明确的级别 + 对应的升级路径,不能让值班工程师在凌晨 3 点靠判断力决定”这个要不要叫醒别人”:
| 级别 | 含义 | 响应时间 | 处理方式 |
|---|---|---|---|
| P0 严重 | 服务完全不可用/数据丢失 | 立即 | 启动应急响应,通知所有相关方 |
| P1 高 | 核心功能受损/大范围受影响 | 15 分钟内 | 立即处理 |
| P2 中 | 非核心功能异常/有临时绕过方案 | 1 小时内 | 正常工作处理 |
| P3 低 | 轻微降级/不影响用户 | 4 小时内 | 排期处理 |
| P4 信息 | 仅通知,无需立即行动 | 下个工作日 | 转工单 |
关键实践:P0/P1 必须配置”升级路径”(Primary 未响应 → Secondary → 负责人),且告警详情里必须直接附带 Runbook 链接,让值班者一打开就知道该干什么。
4. 应急响应:从”混乱”到”有序”
4.1 没有结构的事故响应 = 聊天室的混乱
想象一次大型事故:10 个工程师同时涌入事故群,各自猜测、各自排查,没有人知道”现在到底怎么样了”,也没有人拍板”下一步干什么”。每个高管的私信都在问”情况如何”,而排查的人根本没时间回答。
这就是没有应急响应结构的典型画面。Google SRE 的解决方案是从消防界借来的 ICS(Incident Command System,事故指挥系统):一个人指挥,其他人各司其职,绝不群龙无首。
4.2 四个核心角色
| 角色 | 职责 | 关键原则 |
|---|---|---|
| 指挥官 IC | 唯一决策者 | 不碰键盘,只做决策:问”我们知道了什么、在做什么、谁负责” |
| 技术负责人 SME | 技术排查与止损 | 提出方案、执行排查,向 IC 汇报 |
| 沟通负责人 Comms | 对外通报 | 向用户/高管/内部更新状态,不让 SME 被打断 |
| 记录员 Scribe | 记录时间线 | 记录”几点发生了什么”,让复盘报告自动成型 |
指挥官不是”最资深的人”,而是”拿了指挥帽的人”。 一个新工程师也可以当 IC,资深工程师当 SME——职级不会自动赋予指挥权。交接指挥权时要有正式仪式:“我把指挥权交给 Sarah,Sarah 你接受吗?“并在事故频道公开宣布。
4.3 事故严重级别(以 Google 分级为参考)
| 级别 | 描述 | 示例 | 响应 |
|---|---|---|---|
| Sev0 | 面向客户的大规模故障,重大收入/安全/信任影响 | 登录全挂、支付全挂、数据丢失中 | 完整 ICS 启动,15 分钟内发布状态页 |
| Sev1 | 大量用户或关键流程严重受损 | 搜索坏了、结账错误率 50% | 完整 ICS,状态页每 30-60 分钟更新 |
| Sev2 | 影响有限或有绕过方案 | 单个功能降级、延迟升高 | 轻量指挥结构,超时未解决再升级 |
| Sev3 | 低影响问题 | 次要 UI bug、内部工具慢 | 工作日处理,不需要即时响应 |
重要原则:严重级别要”早声明、勤修订”。 一开始以为是 Sev2,后来发现是数据丢失——一旦确认,立即升级为 Sev0 并公开宣布。最危险的是”悄悄恶化”:事故在扩大,但级别没更新,导致响应资源不足。
4.4 应急响应流程:八步走
1. 确认告警 → 验证告警是否真实(先看 Runbook 的"快速确认"步骤)
2. 评估影响 → 影响多少用户?哪些功能?有无数据风险?
3. 通知相关方 → 按升级路径通知;需要时启动状态页
4. 止血 → 优先恢复服务(回滚/降级/限流/扩容/熔断)
5. 根因分析 → 恢复后定位根本原因
6. 修复 → 实施正式修复(不要用"临时止血方案"当修复)
7. 验证 → 确认指标恢复正常、用户无感
8. 复盘 → 48 小时内完成事故复盘(见《事故复盘方法论》)
4.5 止血手段工具箱
止损阶段的目标是”先让服务恢复,再找原因”。常用手段:
| 手段 | 适用场景 | 说明 |
|---|---|---|
| 回滚 | 新版本引入故障 | 退回上一个稳定版本 |
| 降级 | 非核心功能拖垮核心 | 关闭次要功能,保住主流程 |
| 限流 | 流量冲击 | 丢弃或排队多余请求 |
| 扩容 | 容量不足 | 增加实例/副本 |
| 熔断 | 依赖故障 | 快速失败,不再等待慢依赖 |
| 切换 | 单点故障 | 切换到备用系统/机房 |
原则:止血方案和正式修复要分开。止血方案(如降级)可以先上;但止血不等于修复——后续必须做正式修复,并确认根因,否则事故会以另一种形式复发。
5. Runbook:值班者的”标准操作手册”
5.1 为什么必须写 Runbook
想象你被 3 点的告警吵醒,系统在报警,而你接手这套系统才两个月。此刻你最需要的是什么?一份清晰的”遇到这个告警该干什么”的操作手册——这就是 Runbook(标准操作手册)。
Runbook 的价值:
- 消除”从零排查”:有手册的告警,平均排查时间比没有手册的少 20-30 分钟
- 降低值班门槛:新人也能处理老问题
- 沉淀团队经验:这次踩的坑写进手册,下次就是一条现成的路
5.2 Runbook 模板
# [告警名称] 应急手册
## 告警信息
- 告警名称: HighErrorRate(错误率过高)
- 严重级别: P1
- 触发条件: 5 分钟内错误率 > 5%
- 关联指标: error_rate、请求量
## 影响评估
- 可能影响: 用户请求失败、功能不可用
- 快速判断: 打开 Grafana 看 error_rate 曲线,
确认是整体上升还是某个接口/某台实例上升
## 快速止血(先做这些)
1. 若确认是"新发布引入" → 立即回滚到上一个版本
2. 若确认是"依赖故障" → 切换到备用依赖/降级
3. 若确认是"流量冲击" → 开启限流
## 详细排查(止血后做)
1. 查 error_rate 按接口分组:哪类请求在失败?
2. 查失败日志:错误码是什么?超时?拒绝连接?
3. 查依赖服务健康状态:数据库/缓存/外部 API
4. 查近期部署记录:最近 24 小时发了什么变更?
## 修复方案
1. 临时方案: 回滚 / 降级 / 限流
2. 正式修复: [写明需要改什么代码/配置]
3. 验证: 观察 10 分钟 error_rate 恢复至 < 1%
## 升级路径
- L1: 值班工程师(5 分钟未确认 → 升级)
- L2: 服务负责人
- L3: 技术负责人/架构师
5.3 Runbook 的维护
- 放 Git 仓库(docs/runbooks/),随代码一起版本管理
- 从告警直接链接:每个告警的通知里带上对应 Runbook 链接
- 事故中更新:值班中发现手册有误或缺失,当场补充
- 定期审查:季度检查手册与实际是否一致
6. On-Call 的健康与可持续
6.1 值班的健康红线
- 每班告警 ≤ 2 次(见 2.3 节)
- 每人值班频率 ≥ 间隔 5-6 周
- 值班后有明确的补休/补偿
- 值班压力有人关注(主管定期沟通,不能只看”事故处理得怎么样”)
6.2 把值班当产品来改进
优秀团队会把 On-Call 当”产品”持续改进,目标很简单:让值班越来越轻松。
- 每月统计:告警总数、误报率、MTTR(平均恢复时间)
- 找出最吵的告警:逐条问”这条告警真的需要叫醒人吗?“——不需要就降级/删除
- 找出重复事故:同一类问题反复出现 → 推动根因修复,而不是继续灭火
- 让”系统稳定性”成为团队目标:值班轻松 = 系统健康,这是所有人的共同利益
经典案例(某 SaaS 公司实测):35 人的团队,监控体系长了三年,积累了 340 条告警规则、每周 80+ 条 PagerDuty 告警,其中约一半是误报或自愈。团队花 6 周重构:按 SLO 设计告警、清理无效规则(340 → 87 条)、给每条告警写 Runbook。结果:每周告警从 80+ 降到 11 条,且全部可行动;真实事故的 MTTR 从 47 分钟降到 9 分钟。
这个案例说明:告警变少不是”监控变弱了”,而是”监控变聪明了”——把力气花在真正影响用户的信号上。
7. 常见误区
误区一:告警越多越安全
错误认知:监控越全、告警越多,系统就越安全。
真相:告警太多会让人麻木(告警疲劳),真正出事时反而被忽略。告警的价值不在数量,在”每一条都值得被处理”。
误区二:值班是运维的事,研发不用管
错误认知:On-Call 是运维/值班团队的专职工作。
真相:谁开发谁运维是行业主流原则。研发参与值班,才能写代码时想着”这功能上线后好不好运维”,才能对线上问题有切身体会。
误区三:值班工程师必须”随叫随到、无限扛压”
错误认知:被半夜叫醒是”应该的”,扛不住就是能力问题。
真相:值班压力需要制度化管理——轮值人数、告警上限、补偿机制都是制度问题。如果团队值班体验越来越差,要修的是制度,不是换人。
误区四:Runbook 写一次就完事
错误认知:手册写完放着,系统变了也不更新。
真相:过时的 Runbook 比没有更糟——值班者照着错的步骤操作,可能造成二次事故。手册必须随系统变更同步维护。