很多团队第一次认真设计 On-call,往往是从一张排班表开始的。这个月谁值第一周,谁值第二周,周末怎么轮,节假日谁顶上,电话打给谁。表格排完以后,大家会短暂松一口气:至少故障发生时,总有人能接电话了。
但这只是 On-call 的最低要求,不是一个健康值班体系的目标。真正让人被耗干的,通常不是“轮到我值班”这件事本身,而是值班时收到大量低质量告警、半夜被重复叫醒、接到不属于自己的系统、无人响应时只能硬扛、事故结束后没有补偿和改进。排班表只是把压力分配给人。如果压力的来源没有治理,轮换越公平,只是越公平地消耗每个人。
On-call 机制的目标不是“总有人接电话”,而是让正确的人在正确时间处理正确的问题。这个判断说起来简单,落地时要同时回答五个问题:告警是否值得叫醒人,负载是否可持续,升级路径是否清楚,休息补偿是否被制度承认,复盘是否真的反向改造系统。少任何一项,On-call 都容易退化成轮流背锅。
问题不是没人值班,而是系统把人当缓冲区
很多值班体系的问题,表面看是人手不够。一个人值一周太累,两个人主备也累,节假日没人愿意接,研发和 SRE 互相推责任。继续往下看,往往会发现更深的问题:系统没有把信号、责任和流程整理好,只能靠值班人现场兜底。
一个 Kubernetes Node 抖动,引发几十条 Pod 重启、接口错误率、依赖超时和资源水位告警。如果这些告警没有聚合成一个故障对象,主值班会被连续通知;如果标签里没有稳定的 service、team、env,路由就打不到服务 owner;如果升级规则只有“群里 @ 一下”,没人响应时就靠主值班自己找人;如果复盘只写根因,不修告警规则和 runbook,下次还是同一个人半夜拼上下文。
这类体系里,On-call 人员承担的不是响应职责,而是系统缺陷的缓冲区。他们要过滤噪声、判断影响、找负责人、拉群、追进度、补文档、安抚业务。久了以后,团队会把疲劳归因成“大家不愿意值班”,但真实问题是值班职责被设计得太粗,几乎把所有不确定性都压给了一个人。
一个更实用的框架:五个约束一起设计
健康的 On-call 体系不是一张排班表,而是五个约束的平衡:告警质量、值班负载、升级路径、休息补偿、复盘改进。
第一是告警质量。值班体系必须从告警治理开始,而不是从排班开始。Info 和 Warning 不应该都用电话叫醒人,维护窗口和已知问题不应该进入同样的通知路径,派生告警不应该逐条打给主值班。告警质量差的时候,增加主备值班只是扩大受害面。一个团队如果每周产生大量无人处理、自动恢复、重复触发的 Incident,说明值班人不是在处理故障,而是在做人肉过滤器。
第二是值班负载。负载不是简单的“每个人一周一次”就算公平。白天、夜间、周末、节假日的成本完全不同;半夜一次电话和工作时间一条 IM 消息也不是同一种中断。评估负载时要分时段看中断次数、认领次数、处理时长和连续值班时长。否则,一个人看起来只值了七天,实际上可能承担了整个团队最差的一周。
第三是升级路径。主值班不等于最终责任人。主值班负责第一响应、确认影响、按 runbook 做初步处置,但当问题超出权限、超出能力或超过时间窗口时,系统必须自动升级到备值班、服务 owner、技术负责人或管理层。升级不是“主值班不好意思打扰别人”,而是响应流程的一部分。
第四是休息补偿。On-call 如果只要求可用性,不承认人的恢复时间,迟早会伤害团队。夜间被叫醒后第二天是否可以晚到,周末处理故障是否有调休,连续高压值班后是否暂停下一轮,节假日值班如何补偿,这些都不应该靠口头默契。制度不承认中断成本,团队就会默认把它藏到个人生活里。
第五是复盘改进。每次值班后的数据都应该回到系统:哪些告警低价值,哪些规则该静默,哪些服务总是找不到 owner,哪些升级超时,哪些 runbook 缺失,哪些人长期过载。没有这一步,On-call 只是轮换;有了这一步,它才变成稳定性工程的输入。
主备值班:备不是摆设,也不是第二个主
主备值班最容易被配置成形式主义。页面上有 Primary 和 Backup,实际故障时所有通知同时打给两个人;或者主值班没人响应时,备值班才被临时想起来,规则里并没有明确超时时间。前一种做法浪费人,后一种做法拖慢响应。
更合理的设计是把主备职责写清楚。主值班承担第一响应,负责在规定时间内认领 Incident、判断严重级别、执行初始 runbook、记录关键动作。备值班不是同时处理每条告警,而是在主值班未响应、主值班请求支援、故障升级到 Critical、或处理超过设定时间后介入。备值班也可以承担交接检查,例如确认上一班未关闭的 Incident、临时静默、正在进行的发布和已知风险。
对关键业务,主备可以来自不同角色。比如支付链路的夜间值班,主值班由 SRE 承接第一响应,备值班是支付服务 owner 或研发专家;数据库类告警则主值班可以是 DBA 或平台组,SRE 作为协同和影响面判断的备份。主备的价值不在于“多一个人收到消息”,而在于把第一响应、领域判断和兜底升级拆开。
轮换周期:不要只追求绝对平均
轮换周期没有通用答案。按周轮换便于交接,适合中低频告警和需要持续上下文的系统;按天轮换能降低单人连续压力,但交接成本更高;按昼夜拆分适合夜间中断很重的团队;工作日和周末分开排,适合业务日历差异明显的系统。真正要避免的是把周期设计成看似公平、实际不可持续。
一个常见反例是“一人连续值七天,主备都在”。如果告警质量好,Incident 少,这可能可以接受;如果每天都有夜间电话,这就是把人从工作日一直拖到周末。另一个反例是“每天换人”,但没有交接机制。短周期降低了单人暴露时间,却增加了上下文丢失,第二天的新值班人不知道前一天哪些告警被临时绕过、哪些变更还在观察、哪些问题已经有业务方关注。
所以轮换周期要和告警负载一起调。先看真实数据:夜间和睡眠时段的中断有多少,主值班平均需要处理多久,周末是否显著高于工作日,某些服务是否长期制造噪声。再决定是一周一换、两三天一换,还是按白天/夜间/周末拆不同规则。公平不是每个人排到同样的格子,而是每个人承受的中断成本长期接近,并且有恢复空间。
服务日历:不是所有系统都按同一张日历运行
很多企业的 On-call 规则混乱,是因为把所有服务都按同一个时间表处理。办公系统、证券交易系统、批处理平台、支付链路、内部报表系统,对工作日、休息日、节假日和业务窗口的要求完全不同。用一套 24/7 规则覆盖所有系统,要么叫醒太多人,要么错过真正重要的时段。
服务日历的价值在于把“什么时候应该响应”显式化。交易日的核心系统,开盘前后和交易时段的告警可能需要更高优先级;休息日的低优先级内部系统,可以只保留 IM 通知或延后处理;节假日前后的批处理任务,可能需要临时加强值班。服务日历不是排班表的替代品,它在排班表之上定义时间语义:今天对这个服务来说是工作日、休息日、交易日、维护日,还是高风险窗口。
这也能减少很多组织摩擦。不是每次低优先级告警都要争论“要不要叫醒人”,而是在规则里提前说清楚:什么时段、什么严重级别、什么服务,走哪条通知和升级路径。
服务 owner 什么时候该值班,SRE 什么时候先接
“谁应该 On-call”是很多团队最容易争的地方。服务 owner 认为 SRE 应该负责稳定性平台和一线响应;SRE 认为研发写的服务当然应该研发自己扛。两种说法都有道理,也都不完整。
判断标准应该是故障类型和处置权限。服务 owner 应该为自己能直接修复、回滚、降级、扩容或解释影响的业务服务值班,尤其是核心链路、频繁变更系统、领域知识很重的系统。因为这类问题如果先打给 SRE,SRE 很多时候只能确认“确实异常”,然后再把研发叫起来,MTTA 和 MTTR 都被拉长。
SRE 更适合承接平台型第一响应:基础设施、监控平台、公共组件、网络、集群、容量、跨服务影响判断,以及告警质量仍在治理初期的统一入口。SRE 的价值是快速识别影响面、协调跨团队、执行标准化处置、维护响应体系,而不是替每个服务 owner 永久承担业务故障。
成熟的做法通常是分层:低风险或明确归属的业务告警直接路由到服务 owner 的值班表;跨系统、基础设施或归属不清的告警先由 SRE 接;Critical 级别故障可以同时触达 SRE 和 owner,但职责要不同,一个负责全局协调和状态同步,一个负责领域处置和修复决策。这样既不会让研发逃离生产责任,也不会把 SRE 变成所有业务系统的夜间客服。
落地时怎么做
设计 On-call 不建议从全公司统一制度开始。更稳的做法,是选一个核心系统,用真实告警和最近事故先跑一版。
第一步,清理告警入口。确认这个系统的告警是否有稳定的服务、资源、检查项、环境和团队标签;确认 Event、Alert、Incident 是否分层;把重复、抖动、维护窗口和派生告警先治理掉一批。值班制度不能建立在垃圾告警之上。
第二步,定义响应分层。把告警按严重级别和类型分成几类:需要立即电话的 Critical,需要工作时间处理的 Warning,只做记录的 Info,需要服务 owner 处理的业务问题,需要 SRE 首响的平台问题,需要 DBA、安全、网络等专家介入的专项问题。
第三步,设计值班表。先确定主备角色,再确定轮换周期和交接时间。关键业务可以一周一换,但夜间负载重时应考虑短周期或昼夜拆分;周末和节假日要单独看,不要默认塞进同一条规则。临时请假、出差、发布保障,要用临时替班机制处理,而不是改永久规则。
第四步,配置升级策略。明确主值班多久未认领升级到备值班,多久未关闭或未更新升级到专家或负责人,Critical 是否直接触达多角色,低级别是否只走 IM。升级条件要基于“未认领”和“未关闭”这类可验证状态,而不是靠群里感觉。
第五步,建立值班后复盘。每周或每个轮换周期结束后,至少看四类数据:中断次数、认领率、MTTA/MTTR、人员负载。再挑 TOP 告警资源和检查项,决定要改监控规则、降噪规则、路由标签、runbook、值班表还是服务 owner 归属。
用 Flashduty 如何落地
如果用 Flashduty,这套方法可以落到几个对象上。值班表用于承载“谁在什么时候负责响应”。Schedule 支持日、周、自定义周期,也支持 day/night shift、主备值班、按角色通知、临时 Override、日期掩码和公平轮换。这里最重要的不是把所有功能都打开,而是把你的职责模型映射进去:哪些人是主值班,哪些人是备值班,交接时间是什么,节假日和周末是否单独规则,临时替班是否留下记录。
服务日历用于承载“这个服务在什么时间按什么语义处理”。它可以被升级规则或静默规则引用,用来区分工作日、休息日、业务日、节假日等场景。对业务时间窗口强的系统,这比单纯写固定时间段更可靠。
升级策略用于承载“没人响应或处理不完时怎么办”。Flashduty 的 Escalation Rules 可以按 Incident 严重级别、标签、时间和服务日历匹配规则,通知当前值班表、团队或个人,并通过 IM、App、短信、电话、邮件等渠道触达。更关键的是多级升级:主值班未认领可以升级到备值班,未关闭可以升级到服务 owner 或技术负责人,Critical 可以走更强触达。
人员负载分析用于承载“这个体系是否可持续”。Insights 里可以按团队、channel、个人和时段看 Incident、MTTA、MTTR、响应率、响应投入和中断次数,并把工作时间、休息时间、睡眠时间分开。这个视角很重要,因为 On-call 的问题往往不是总量,而是夜间和休息时段的中断集中到了少数人身上。
验收标准:不是排满,而是可持续
一套 On-call 体系做得好不好,不看排班表是不是没有空格,而看几个更具体的结果。
第一,Critical 告警是否能在规定时间内被认领,且认领人确实有处置路径。第二,低质量告警是否持续下降,尤其是夜间自动恢复、重复触发、无人处理的 Incident。第三,主备升级是否真的发生过、可追溯,而不是停留在制度文本里。第四,服务 owner 和 SRE 的边界是否越来越清楚,归属不明的告警是否越来越少。第五,值班负载是否长期均衡,睡眠时段中断是否被单独统计和治理。第六,复盘是否能反向产生告警规则、路由、runbook、值班表和服务日历的改进。
如果这些指标没有变化,排班再整齐也只是管理动作。如果这些指标开始变好,On-call 才真正从“有人接电话”变成“系统帮助人稳定地响应故障”。
On-call 不应该是轮流背锅。它应该是一套把生产责任、响应流程和人的恢复能力都认真设计进去的机制。告警质量决定值班是否值得,负载数据决定轮换是否公平,升级路径决定主值班是否会被困住,休息补偿决定体系能不能长期运行,复盘改进决定下一轮值班会不会更轻。
下一步可以很小:先选一个核心系统,下载 On-call 轮班模板,或创建第一张值班表。不要一开始就追求覆盖所有团队,先用一条真实告警链路验证主备、轮换周期、服务日历、升级策略和人员负载数据。跑完一个周期,再决定该扩展值班范围,还是先治理告警质量。