想象你是一座“数字大厦”的消防局调度员。大厦里住着上亿“用户”,他们不关心大厦内部怎么运转,只关心灯有没有亮、电梯有没有坏。你的职责不是保证大厦永不冒烟——那不现实——而是保证冒烟之后,消防员能在承诺的时间内到场、把火扑灭、然后回到值班室复盘:这次为什么烟气没被提前拦住? 这座大厦的消防值班室,就是 AI 系统可观测性中的 On-call 轮值制度。一排排监控屏幕对应告警体系,墙上的岗哨牌对应排班表,三级火警对应告警升级路径,烟感器的误报对应告警噪音,火灾后的战评会对应事故复盘。而那块写着“15 分钟内到场”的承诺牌,就是 SLO(服务级别目标)。 这篇文章会带你从零建起这座值班室:先排班,再定升级路径,然后清噪音,接着搞复盘,最后把 SLO 当作指挥棒贯穿始终。你还会看到 AI 系统这支“特殊消防队”和普通消防队有什么不同,以及值班工程师手边该有一整套怎样的应急工具包。

岗位关联

对 AI 从业者来说,On-call 不是“半夜收告警邮件”,而是一套可设计、可度量、可持续的工程纪律。掌握它,你才能从“写代码的人”成长为“对系统负责的人”。

目录
  1. 可视化演示
  2. 值班排班规则:门后的岗哨牌
  3. 告警升级路径:火警的三级响应
  4. 噪音消除策略:让铃声不再狼来了
  5. 复盘改进闭环:火灾后的战评会
  6. SLO联动设计:消防队的承诺红线
  7. AI系统特殊性:实验室里的消防喷淋
  8. 轮值工具链:消防员的应急包
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

通过轮值排班、告警升级路径与无指责复盘三模式,展示AI系统On-call轮值制度的核心机制与最佳实践。

本节配有交互动效(进入视口后自动加载,约 3KB)。

轮值排班机制 四成员按周轮值,每周一人主值班,确保7x24小时覆盖 覆盖率=T(覆盖)/T(总) 合理排班避免疲劳

值班排班规则:门后的岗哨牌

消防局的走廊里挂着一块白板,上面写着本周谁当消防员、谁当备勤。别小看这块板子——如果岗哨牌写得模糊,火警响起时大家会互相张望,甚至出现两辆消防车撞进同一栋楼、另一栋楼却没人管的情况。数字大厦的 AI 系统同样需要一块“岗哨牌”,这就是 On-call 排班表。

排班表不是简单地轮流签名。它至少要做好四件事:班次划分(主班负责一线响应,副班负责幕后支援)、交接仪式(交班时把遗留告警、临时变更口口相传地交接清楚)、负载均衡(统计每个人处理过的告警量,避免总让老实人多干)、休假保障(节假日和年假自动跳过)。这些规则听起来像行政琐事,却是七乘二十四值守的基石。

要量化排班是否公平,可以用负载均衡系数:

白板上的名字轮流更替,但规则始终不变:每个人都可能在深夜接到电话,也每个人都值得在白天安睡。岗哨牌的背后,是对“人”的尊重。

E=1−∣LA−LB∣LA+LB\displaystyle E = 1 - \frac{|L_A - L_B|}{L_A + L_B}
E 越接近 1,说明 A、B 两位工程师的告警负担越均衡;E 偏低时,就该在例会上调整排班了。
  1. 统计值班负担 \(L_A\) 与 \(L_B\)分别统计 A、B 两位值班工程师在统计周期内实际处理的告警响应数量,这是公平排班的事实依据。
    LA=∑alerts handled by A,LB=∑alerts handled by BL_A = \sum \text{alerts handled by A}, \quad L_B = \sum \text{alerts handled by B}
  2. 计算差距占比 \(|L_A - L_B|/(L_A + L_B)\)用两人负担的绝对差除以总负担,得到一个 0 到 1 之间的比例,衡量排班的“偏心程度”。
    ∣LA−LB∣LA+LB\frac{|L_A - L_B|}{L_A + L_B}
  3. 转化为均衡度 E用 1 减去差距占比,让数值越大表示越均衡,方便排班例会直观对比。
    E=1−∣LA−LB∣LA+LBE = 1 - \frac{|L_A - L_B|}{L_A + L_B}

告警升级路径:火警的三级响应

消防队有一套默认剧本:接到火警电话,先派一辆消防车侦察;若是浓烟火光,立即升级为全员出动并向邻近支队请求增援;再不行,总指挥到场成立现场指挥部。这套“由小到大、层层呼叫”的机制,在数字大厦里叫告警升级路径。

告警按严重程度分为 P1、P2、P3 三级,对应消防的火情分级。响应时限是最底层的承诺:从告警发出到值班工程师点击“认领”,往往要求在几分钟内完成。升级分级指如果超时未确认、或确认后多次处理仍无法缓解,系统会自动把告警推送给更高级别的负责人。应急指挥对应指定一名应急指挥官(Incident Commander),由他统筹“救火”,不让工程师满场乱跑。事态公告则是同步更新给相关方,像消防队用扩音器喊话一样,避免业务方反复来问“好了没”。

响应时限的预算可以表达为:

火警响铃不是为了让消防员紧张,而是为了让该听的人听到、该到的人赶到。每一级升级,都是一句潜台词:“这一步的火,超出当前这只消防队的控制力了。”

Ttarget=Tack+Tmitigation≤15 min\displaystyle T_{\text{target}} = T_{\text{ack}} + T_{\text{mitigation}} \leq 15 \ \text{min}
从告警发出到确认、再到完成止血操作,合计不能超过 15 分钟。这是 SLO 承诺的响应红线。
  1. 确认时间 \(T_{\text{ack}}\)告警发出到值班工程师按下“认领”按钮的耗时。在消防队,这段时长对应火警电话接通后消防员跳上车的时间。
    Tack=tack−tfireT_{\text{ack}} = t_{\text{ack}} - t_{\text{fire}}
  2. 缓解时间 \(T_{\text{mitigation}}\)从确认到完成止血操作(回滚、扩容、降级)的耗时,对应消防车抵达火场到火势被压制的间隔。
    Tmitigation=tresolved−tackT_{\text{mitigation}} = t_{\text{resolved}} - t_{\text{ack}}
  3. 合计并对比红线把两段耗时相加,与 15 分钟的承诺红线作比较,超时即视为一次响应违规,需要触发升级或记录复盘。
    Tack+Tmitigation≤15 minT_{\text{ack}} + T_{\text{mitigation}} \leq 15 \ \text{min}

噪音消除策略:让铃声不再狼来了

消防队的电话不是没接过乌龙:烧烤摊冒烟、婚礼放烟花、有人在楼道里煮糊了火锅。每一次误报都占用了一车人的时间,更可怕的是“狼来了”效应——当消防员被垃圾警报折腾了十次后,第十一次真火警响了,他们可能还会犹豫三秒。

告警噪音是 On-call 团队最大的隐形敌人。噪音来源千奇百怪:阈值设置过于灵敏、监控指标在维护窗口内正常抖动、同一故障触发了几十条相似告警。阈值调优是第一步——让告警只在“真的需要人类介入”时才响。维护静默是在计划维护时间段内直接屏蔽预期内的波动。告警聚合把同一根因的多条告警合并成一条,像消防支队把所有相同地址的报警电话合并成一场火情。

衡量告警“净不净”有一个直观指标——告警有效度:

消防队的目标不是响最多的铃,而是救最多的火。告警体系同理:让每一次铃声响起时,消防员都能毫不犹豫地穿上战斗服。

V=NrealNtotal\displaystyle V = \frac{N_{\text{real}}}{N_{\text{total}}}
V 越接近 1,说明告警噪音越少;V 明显偏低时,值班工程师的注意力正在被白白消耗。
  1. 统计 \(N_{\text{total}}\)统计一个时间窗口内触发的全部告警条数,包括真实故障与各类误报,这是噪音问题的分母。
    Ntotal=Nreal+NfalseN_{\text{total}} = N_{\text{real}} + N_{\text{false}}
  2. 统计 \(N_{\text{real}}\)人工复核后确认真正需要响应的告警条数,代表告警体系里的“信号”部分。
    Nreal=true positivesN_{\text{real}} = \text{true positives}
  3. 相除得到有效度 V信号量除以总量。V 低时优先治理噪音,而不是继续堆叠告警规则。
    V=NrealNtotalV = \frac{N_{\text{real}}}{N_{\text{total}}}

复盘改进闭环:火灾后的战评会

一次大火被扑灭后,消防队长不会解散队伍让大家回去睡觉,而是会把所有人叫回会议室开战评会。先拼时间线:第一通电话几点打来?消防车几点到达?水压什么时候不够的?然后问五个“为什么”,最后落成几条改动。这一幕在数字大厦里的翻版,就是事故复盘(Postmortem)。

复盘的第一个动作是时间线还原——把所有关键事件按分钟对齐,看哪一环拖慢了恢复。接着用根因五问法往下挖:告警为什么没看到?因为被三百条噪音淹没了;为什么噪音这么多?因为阈值三年没调;为什么阈值没人调?因为没有责任人……一直挖到流程漏洞。整个过程必须浸泡在无指责文化里——不追责“谁放的火”,只研究“为什么消防通道是堵的”。最后产出行动跟进表,每条改进都要有负责人和截止日期,否则复盘就只是自我感动。

衡量修复速度的核心指标是平均修复时间(MTTR):

战评会不是审判庭,而是体检室。消防队的进步不是靠惩罚谁多抽了一根烟,而是靠把“下一次会更好”变成一句有步骤、有期限、有责任人的承诺。

MTTR=1N∑i=1NTi\displaystyle \text{MTTR} = \frac{1}{N} \sum_{i=1}^{N} T_i
MTTR 越低,说明从告警触发到业务恢复的整体速度越快,它是复盘效果的“体检报告”。
  1. 单次修复时长 \(T_i\)第 i 次事故从告警触发到服务完全恢复的总时长,包含确认、定位、止血、验证四个环节。
    Ti=trecovered,i−ttriggered,iT_i = t_{\text{recovered},i} - t_{\text{triggered},i}
  2. 求和再除以 N把最近 N 次事故的修复时长累加取平均,压平偶发长尾事故的波动,得到团队基准水平。
    1N∑i=1NTi\frac{1}{N} \sum_{i=1}^{N} T_i
  3. 解读 MTTR 变化每次复盘后比较 MTTR 是否下降,若长期不降,说明改进项没有被真正落地,需要检查行动跟进表。
    MTTR=1N∑i=1N(trecovered,i−ttriggered,i)\text{MTTR} = \frac{1}{N} \sum_{i=1}^{N} (t_{\text{recovered},i} - t_{\text{triggered},i})

SLO联动设计:消防队的承诺红线

消防局门口挂着一块牌:“接到火警后 15 分钟内到场”。市民不会要求消防队保证“永不发生火灾”,因为火灾总会发生;他们会要求的是“发生之后你多久能到”。这句话翻译成可观测性语言,就是服务级别目标 SLO:我们承诺系统在 99.9% 的时间里可用,剩下 0.1% 的不可用时间是官方允许的“错误预算”。

错误预算是 SLO 设计的核心概念。若月度 SLO 是 99.9%,那么一个月允许的总故障时间只有约 43 分钟,这 43 分钟就是消防队的“火情配额”。告警阈值不能凭拍脑袋,而应锚定错误预算的消耗速率——当消耗速度远超时间流逝速度时,立刻告警。缓解窗口指在预算耗尽之前主动采取的止血动作,比如暂停新模型发布。仪表盘把预算消耗画成进度条摆在团队眼前,让每个人都知道“这个月我们还剩多少分钟可以烧”。

错误预算消耗速率可以定量表达:

红线不是用来踩的,而是用来提前比对的。消防队不会等到火都烧到隔壁街区才开始想办法,数字团队也一样:真正的专家不是“救火最快的”,而是“让火根本烧不起来”的。

R=EusedTelapsed\displaystyle R = \frac{E_{\text{used}}}{T_{\text{elapsed}}}
R > 1 表示预算消耗快于时间流逝,系统正以危险速度逼近 SLO 红线,此时应冻结发布、专注稳定性。
  1. 已消耗预算 \(E_{\text{used}}\)统计周期内累计的故障时长(分钟),用它除以月度总预算,就能算出“火情配额”用了多少。
    Eused=∑outage minutesE_{\text{used}} = \sum \text{outage minutes}
  2. 时间流逝 \(T_{\text{elapsed}}\)统计周期已过去的分钟数,作为公平的参照系——预算应该和时间同步“燃烧”。
    Telapsed=current minute of monthT_{\text{elapsed}} = \text{current minute of month}
  3. 相除得到消耗速率 RR = 1 是理想匀速线;R > 1 时系统消耗过快,触发告警并进入防守模式。
    R=EusedTelapsedR = \frac{E_{\text{used}}}{T_{\text{elapsed}}}

AI系统特殊性:实验室里的消防喷淋

数字大厦里有一层楼很特殊——那里不是普通居民区,而是摆满 GPU 服务器和模型推理服务的“实验室”。实验室的消防系统和商场完全不同:不能用普通水喷淋(会短路算力设备),要备特殊的灭火剂;要监控的不只是温度,还有“数据浓度”和“模型状态”。这就是 AI 系统 On-call 的特殊性。

传统 Web 服务盯 CPU、内存、流量就够,AI 系统却要多盯几样东西:模型漂移——线上数据的分布悄悄变了,模型还在用旧规则答题,准确率无声下滑;数据质量——上游标签延迟、样本缺失,训练管道喂了变质的原料;GPU 集群——算力卡坏一张、显存泄漏、租户互相抢资源,故障模式比普通服务器丰富得多;灰度回滚——新模型发布不能一刀切,必须先切 5% 流量观察,出问题要能秒级回滚。

在线模型的健康度可以用准确率漂移检测来监控:

实验室的喷淋头要按化学品特性来装,AI 系统的告警也要按模型和数据特性来设计。把模型当普通服务来监控,就像把水直接泼上电路板——救火反而变成了纵火。

Acconline≥Accbaseline−δ\displaystyle \text{Acc}_{\text{online}} \geq \text{Acc}_{\text{baseline}} - \delta
线上模型的实际准确率如果跌破“基线减容忍度”,就触发告警,提示可能发生模型漂移。
  1. 计算真实线上准确率 \(\text{Acc}_{\text{online}}\)用有反馈标签的线上数据算实际准确率,它是模型在真实世界里的答卷。
    Acconline=NcorrectNfeedback\text{Acc}_{\text{online}} = \frac{N_{\text{correct}}}{N_{\text{feedback}}}
  2. 对比离线基线 \(\text{Acc}_{\text{baseline}}\)把线上表现和上线前的评测基线比较,差值超过容忍度 \(\delta\) 就说明环境变了。
    Δ=Accbaseline−Acconline\Delta = \text{Acc}_{\text{baseline}} - \text{Acc}_{\text{online}}
  3. 触发漂移告警当 \(\Delta > \delta\) 时,系统应发出模型漂移告警,并建议回滚或重新训练。
    Acconline≥Accbaseline−δ\text{Acc}_{\text{online}} \geq \text{Acc}_{\text{baseline}} - \delta

轮值工具链:消防员的应急包

消防员出警不是空手去的。对讲机、防火服、破拆斧、记录板,整套装备提前装进背包,火场里才知道该用哪件。On-call 工程师也一样,光有排班和告警还不够,还得有一个趁手的“应急包”——轮值工具链。

统一工作台把散落在各平台的告警、工单、指标汇聚到一个界面,值班工程师不用在十几个系统间来回横跳。自动化诊断把高频故障的诊断步骤固化成脚本或 Runbook——告警一响,自动拉取最近的模型版本、GPU 利用率、数据管道延迟,先查一步再叫醒人类。知识库沉淀历史事故和解决方案,新值班的人遇到旧问题能像查菜谱一样查到做法。报告生成自动整理值班小结和复盘材料,不再让工程师在凌晨三点还要手写日报。

工具链的成熟度可以用自动化覆盖率来衡量:

应急包里的每一样工具,都是为了同一个目的:让战士在战场上少想一秒。工具链不是替代 On-call 工程师,而是把他们的精力留给真正需要人类判断的火情。

C=NautoNtotal\displaystyle C = \frac{N_{\text{auto}}}{N_{\text{total}}}
C 表示无需人工介入就能自动处理或预诊断的告警占比。覆盖率越高,值班工程师的有效战斗力越强。
  1. 自动处理告警数 \(N_{\text{auto}}\)统计由脚本自动诊断、甚至自动止血(如重启实例、回滚模型)的告警数量。
    Nauto=auto-resolved alertsN_{\text{auto}} = \text{auto-resolved alerts}
  2. 告警总数 \(N_{\text{total}}\)同一周期内出现的全部告警数量,作为覆盖率的分母。
    Ntotal=all alertsN_{\text{total}} = \text{all alerts}
  3. 相除得到覆盖率 CC 越高,说明工具链把值班工程师从重复劳动中解放得越好,可以把精力留给真正需要人类判断的火情。
    C=NautoNtotalC = \frac{N_{\text{auto}}}{N_{\text{total}}}

AI 应用场景

场景一:大模型推理服务的告警升级与值班排班

阶段:模型上线与运维监控

解决的问题:大模型 API 每天承载上亿次请求,任何一次推理延迟飙升都会直接影响用户体验。传统方式是让运维手动盯控制台,发现异常再互相打电话通知,响应慢且没有固定排班;AI 服务还存在“静默降级”——模型没有崩溃,但回答质量悄悄变差。

具体案例:某大模型服务团队设计了 P1/P2/P3 三级告警体系:P3 单条请求超时只记日志;P2 连续五分钟 p99 延迟超两秒触发值班确认;P1 错误率突增 10% 且 15 分钟无人响应时自动升级到 SRE 主管,同时发全员公告群。值班排班按周轮换,周五下午做交接仪式,周末自动切换负责人,并用负载均衡系数定期校准排班表。

场景二:推荐系统模型漂移的 SLO 告警

阶段:模型监控与反馈闭环

解决的问题:推荐模型的线下 AUC 看起来很好,上线后用户行为分布悄然变化,准确率无声下滑。如果靠人工每天对比线下线上指标,既不现实也容易遗漏;更危险的是,漂移常常在前几天毫无症状,直到某天业务指标骤降。

具体案例:MLOps 团队为线上模型设置了准确率漂移告警:实时采集用户反馈,每小时计算一次在线准确率,当连续三个窗口低于基线两个百分点时触发 P2 告警,自动拉取近一小时的样本分布对比,并暂停当日模型推送。复盘时用根因五问法发现是数据管道延迟导致新用户特征缺失,随后在知识库沉淀了“特征延迟排查手册”。

场景三:GPU 集群容量告警与值班交接

阶段:基础设施调度与容量规划

解决的问题:多租户 GPU 集群中,某个训练任务突然占用全部显存,导致其他推理服务 OOM。传统靠值班人员逐个看监控面板,难以快速定位是谁抢了资源;AI 训练任务的故障模式又比普通应用复杂,常见故障如显存泄漏、驱动异常、NVLink 断链。

具体案例:基础设施团队在统一工作台上聚合了 GPU 利用率、显存占用、租户配额三条告警链,自动化诊断脚本会在告警触发的同时抓取 top10 显存进程与租户归属,Runbook 自动附上“建议:强制重启任务 A 或扩容集群”。值班交接时,交班人只需在知识库中留一条“今日变更 + 遗留告警 + 处理建议”便可离开。

Python 演示

python84 行
# -*- coding: utf-8 -*-"""On-call 值班与告警升级模拟器"""import randomimport time  class Alert:    """一条告警记录"""     def __init__(self, alert_id, severity):        self.alert_id = alert_id        self.severity = severity    # P1 / P2 / P3        self.born = time.time()     # 触发时间戳        self.escalated = False      # 是否已升级        self.resolved_at = None     # 解决时间戳        self.acked = False          # 是否已被确认        self.ack_time = None        # 确认时间戳  class OncallEngine:    """模拟值班工程师处理告警的引擎"""     def __init__(self, ack_deadline=3.0, esc_deadline=6.0):        self.ack_deadline = ack_deadline    # 确认时限(秒)        self.esc_deadline = esc_deadline    # 升级时限(秒)        self.active = []                    # 活跃告警列表        self.done = []                      # 已解决告警列表        self.esc_count = 0                  # 升级次数统计        self.ack_count = 0                  # 正常确认次数统计     def receive(self, alert):        """接收一条新告警"""        self.active.append(alert)        print("[%s] 收到告警 #%d" % (alert.severity, alert.alert_id))     def check(self, now):        """检查每一条活跃告警是否超时"""        for a in self.active[:]:            age = now - a.born            # 值班工程师在时限内响应(模拟 80% 概率及时确认)            if age >= self.ack_deadline and not a.acked:                if random.random() < 0.8:                    a.acked = True                    a.ack_time = now                    self.ack_count += 1                    print("[%s] 告警 #%d 已被值班工程师确认" %                          (a.severity, a.alert_id))            # 超时未确认则自动升级到 L2            if age >= self.esc_deadline and not a.escalated:                a.escalated = True                self.esc_count += 1                print("[%s] 告警 #%d 超时未确认 -> 升级到 L2" %                      (a.severity, a.alert_id))            # 升级后由 L2 介入并自动缓解            if a.escalated and age >= self.esc_deadline + 2.0:                a.resolved_at = now                self.done.append(a)                self.active.remove(a)                print("[%s] 告警 #%d 由 L2 处理完成" %                      (a.severity, a.alert_id))  def main():    """运行 30 秒模拟并打印统计"""    random.seed(7)    engine = OncallEngine()    alert_id = 0    start = time.time()    while time.time() - start < 30:        if random.random() < 0.12:            alert_id += 1            sev = random.choice(["P1", "P2", "P3"])            engine.receive(Alert(alert_id, sev))        engine.check(time.time())        time.sleep(0.2)    print("\n=== 模拟结果 ===")    print("产生告警: %d 条" % alert_id)    print("正常确认: %d 次" % engine.ack_count)    print("升级次数: %d 次" % engine.esc_count)    print("已解决: %d 条" % len(engine.done))  if __name__ == "__main__":    main()
目的:模拟随机告警流经 On-call 值班系统时,工程师及时确认、超时升级到 L2、最终自动缓解的完整流程,演示升级路径的核心逻辑。
  1. engine = OncallEngine()创建值班引擎,参数 ack_deadline 是确认时限,esc_deadline 是升级时限,对应正文中的两级红线
  2. if random.random() < 0.8:模拟值班工程师 80% 情况下能在限时内确认告警,剩下的 20% 会触发升级路径
  3. if age >= self.esc_deadline and not a.escalated:告警超时未确认时自动升级,这是升级路径的落地点
  4. if a.escalated and age >= self.esc_deadline + 2.0:升级后的告警由 L2 介入并自动缓解,避免告警永久卡在队列里
  5. print("[%s] 告警 #%d 超时未确认 -> 升级到 L2" % ...)升级动作可观测、可审计,为复盘留下证据

常见误区

误区我把所有监控指标的告警阈值都设得非常低,结果值班手机一晚上响五十次,同事都说我认真负责,我也觉得多响总比漏掉好。

正解告警体系的 KPI 不是“响得多”,而是“响得准”。消防队如果每根烟头都触发火警,真正的浓烟反而没人信。要用告警有效度 V 来度量,把噪音源(阈值过灵、维护抖动、重复告警)逐项清理,让每一条铃声都值得工程师爬起来看一眼。

为何常见:多告警在直觉上等于“看得紧”,但实际上人类的注意力会被噪声瞬间击穿,反而漏掉真正的故障。

误区P1 超时就要叫醒主管,万一只是误报,显得我很无能,所以我把升级时间设成 24 小时,等于没有升级。

正解升级路径是告警体系的安全网,不是考核工具。消防分级的目的正是“小火星不出警,大火全队上”。超时自动升级能防止告警躺在队列里无人认领酿成大祸;误报升级在无指责文化下只是成本很低的小插曲,而“无人响应”才是真正的生产事故。

为何常见:人天然害怕“小题大做”被评价,却低估了“告警无人认领”才是系统最危险的沉默。

误区复盘就是查是谁的锅,写进绩效,让当事人当众检讨,下次就没人敢犯错了。

正解有效复盘的核心是无指责文化:不是问“谁”,而是问“为什么系统允许他犯错”。用时间线还原和根因五问法找出流程、指标、工具的缺口,再落到有负责人和截止日期的行动项上。消防队战评会研究的是“消防通道为什么堵”,而不是“谁放的火”。

为何常见:归因于个人是最省力的解释,可惜它只会让问题隐藏得更深,下次换个姿势再爆炸一次。

误区这个月 SLO 还剩一堆错误预算没用完,不发布新模型就“亏”了,于是集中上线高风险变更把预算“花掉”。

正解错误预算不是给团队绩效做指标的额度,而是用户可容忍的故障上限。预算剩得多说明系统很稳,应该继续保持观察而非加速冒险;预算烧得过快时,应该冻结发布、补齐监控,防守才是正确的动作。

为何常见:把“可用性承诺”误解成“绩效余额”,本质上是不理解 SLO 是面向用户的约束,而不是面向团队的奖励池。

误区把几千条告警推到 App 上就万事大吉了,谁有空谁看,不用排班也不用交接,反正手机都会响。

正解On-call 是一个完整的运营体系:排班表解决“谁负责”,交接文档解决“上一班留下了什么”,升级路径解决“处理不了怎么办”,复盘解决“下次怎么更快”。没有这套机制,告警 App 只会变成一部凌晨三点响个不停的电话。

为何常见:工具能轻易触达我们,让人误以为“触达即值守”,忽略了责任边界和可持续性设计。

面试题

Q1. On-call 轮值制度的核心目的是什么?

单选题 · easy

  • A.让工程师一周七天随叫随到
  • B.让团队轮流承担故障响应← 正确答案
  • C.用技术手段彻底消灭告警
  • D.精确记录每人加班时长

答案:B。On-call 轮值的本质是把“随时可能发生的故障响应”变成一种可持续的排班制度,让大家轮流承担而不是少数人扛下所有。A 是手段不是目的,C 不现实,D 是行政管理而非核心目的。

Q2. P1 告警超时未确认时,正确的做法是什么?

单选题 · easy

  • A.自动降级为 P3 稍后处理
  • B.等待工程师自然发现
  • C.按升级规则自动通知上级← 正确答案
  • D.直接关闭告警避免打扰

答案:C。升级路径是安全网。告警超时未确认意味着当前层级无人响应,系统应该自动把事件推给更高级别的负责人,而不是等待、降级或关闭。就像消防火势变大时要请求增援,而不是原地等消防员睡醒。

Q3. AI 系统相比传统 Web 服务,On-call 需要新增哪类监控?

单选题 · easy

  • A.服务器的 CPU 与内存利用率
  • B.模型漂移与数据质量变化← 正确答案
  • C.数据库连接数与慢查询数量
  • D.代码仓库的提交频率与分支数

答案:B。AI 系统的“软故障”体现在模型和数据层面:线上分布漂移、特征延迟、标签缺失都会让模型静默变质。传统 Web 的 CPU、数据库指标依然要盯,但它们是通用维度,不是 AI 特有的新增维度。

Q4. 错误预算的作用是什么?

单选题 · mid

  • A.用来计算工程师的绩效奖金
  • B.衡量可用性余量并驱动发布决策← 正确答案
  • C.控制云服务商的账单开销
  • D.限制用户访问系统的时间窗口

答案:B。错误预算 = 用户可以容忍的故障上限。预算充足时可以大胆发布新模型,预算烧得太快则要冻结上线、专注稳定性。它是连接 SLO 与发布流程的决策纽带,与奖金、云账单、用户限时无关。

Q5. 告警有效度 V = N真实 / N总告警 接近 1 说明什么?

单选题 · mid

  • A.告警系统灵敏度高,漏报很少
  • B.大多数告警都是真实故障← 正确答案
  • C.值班工程师响应速度快
  • D.系统故障发生频率很低

答案:B。V 衡量的是“信号在所有告警中的占比”。V 高说明告警噪音少,每一条响铃都值得处理。它不涉及漏报率(A)、响应速度(C)或故障频率(D)。

Q6. 以下哪项最能体现“无指责复盘”的原则?

单选题 · mid

  • A.找到导致事故的个人并追责
  • B.用奖惩制度约束工程师行为
  • C.修复流程与工具缺陷而非追责← 正确答案
  • D.要求全体加班至问题解决

答案:C。无指责复盘的关注点是系统性问题:为什么流程允许这个错误发生?为什么监控没有提前发现?目标是把缺口补上,而不是找一个人背锅。消防队的战评会研究消防通道为什么堵,而不是处罚放烟火的孩子。

Q7. 错误预算消耗速率 R > 1 意味着什么?

单选题 · hard

  • A.本月系统非常稳定,预算充足
  • B.预算消耗快于时间流逝,需防守← 正确答案
  • C.告警次数超过了上月两倍
  • D.工程师值班时长超出预算红线

答案:B。R = 预算消耗量 / 时间流逝量。R > 1 说明故障累积速度超过了时间推进速度,照此趋势月底会击穿 SLO 红线,所以应暂停发布、集中降风险。它和告警次数、值班时长的统计口径不同。

Q8. 模型漂移正在发生时,哪组行动次序最符合 On-call 最佳实践?

单选题 · hard

  • A.先回滚止血再复盘找根因← 正确答案
  • B.先找代码 Bug 再考虑回滚
  • C.先追责数据管道负责人
  • D.先扩大流量观察漂移趋势

答案:A。On-call 的第一原则是止血优先:先回滚到上一个稳定版本恢复服务,再用根因五问法找到漂移源头。B 把排查放在回滚前会延长故障时间,C 违背无指责文化,D 会让漂移影响更多用户。

Q9. 哪些做法能有效降低告警噪音?

多选题 · mid

  • A.调整阈值减少无意义触发← 正确答案
  • B.维护窗口期屏蔽预期波动← 正确答案
  • C.相似告警聚合为一条事项← 正确答案
  • D.关闭所有非 P1 级别告警

答案:ABC。阈值调优、维护静默、告警聚合是降噪三板斧。D 太极端——非 P1 告警承载着早期预警功能,全部关闭会失去发现潜在问题的机会,属于因噎废食。

Q10. 合理的 On-call 轮值排班应包含哪些要素?

多选题 · mid

  • A.固定班次与明确的交接仪式← 正确答案
  • B.值班负载的均衡统计与调整← 正确答案
  • C.休假期自动跳过值班轮次← 正确答案
  • D.新员工入职首周即独立值班

答案:ABC。排班三要素是班次交接、负载均衡、休假保障,这保证制度可持续。D 错误——新员工需要先跟随副班熟悉系统,直接独立值班会提高误判风险,消防队也不会让新兵单独出警。

Q11. 当 AI 模型在线准确率显著下降并触发告警时,按完整复盘流程应做哪些事?

多选题 · hard

  • A.先用根因五问法还原数据特征变化← 正确答案
  • B.检查训练与线上数据的分布差异← 正确答案
  • C.立即回滚到上一个稳定版本止血← 正确答案
  • D.将模型训练代码全部推倒重写

答案:ABC。标准响应是“止血—定位—改进”的闭环:先回滚恢复线上,再用根因五问和分布对比定位漂移来源,最后落成行动项。D 是极端反应,漂移大概率是数据或环境问题,重写代码既无必要又带来巨大风险。

Q12. 值班交接仪式最主要的目的是什么?

单选题 · easy

  • A.让交班人展示一天的工作量
  • B.传递遗留告警与当前系统状态← 正确答案
  • C.检查值班日志是否填写完整
  • D.确认下一位值班人的到岗时间

答案:B。交接的核心是让下一班对“当前局势”有完整认知:有哪些未处理告警、最近做过什么变更、有什么坑要避开。它像消防队交接时说明“三楼还有一名被困人员,后楼梯有浓烟”,而不是走过场式的寒暄。