前置知识: Git

On-Call 最佳实践

16 min中级

值班制度、告警管理、轮值策略与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 规则四:每次交接都要有仪式

交接是轮值制度里最容易被忽视、也最昂贵的环节。值班交接不只是一句话”我下班了你上”,而是一次结构化的信息传递。

交接至少覆盖四件事:

  1. 进行中的事故:当前有没有未处理完的故障?进展如何?
  2. 持续关注项:有哪些”已知的坑”?比如某个告警最近总是误报、某个依赖下周要发新版
  3. 本周变更:这周部署了什么?下一个值班者需要知道哪些变更可能引起问题
  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 比没有更糟——值班者照着错的步骤操作,可能造成二次事故。手册必须随系统变更同步维护。