9.8

查看英文版

9.8 待命与运营准备度

概述与动机

此刻有人正醒着,因为你的系统可能会呼叫他们。待命(on-call)是一种人力安排,确保在任何时刻都有合格的人能够及时响应生产问题;而运营准备度(operational readiness)则是你在此之前所做的工作,让这个人有真正应对问题的机会。本章讲的正是这种准备工作和这套人力制度:如何设计一个人们能够持续多年而不崩溃的轮值安排,如何判断什么问题值得把人叫醒,以及在让一项服务承载真实流量之前,如何确保它真正做好了被运营的准备。

请将本章与两个相邻主题区分开。第 9.3 章讲的是事件管理,即某个问题已经发生故障后的响应流程:指挥角色、严重级别、协调,以及事后总结。第 9.1 章讲的是站点可靠性工程(SRE),一门更宏观的学科,用服务水平目标和错误预算来工程化地保障可靠性。本章处于事件发生之前、与该学科并行的位置。它问的是一个更狭窄、更贴近个人的问题:这项服务是否真正准备好运行,携带呼叫器的人是被安排去成功,还是被安排去受苦?一个组织可以拥有出色的事件处理流程,却依然让工程师精疲力竭,因为待命的痛苦程度早在任何事件发生之前,就由告警的质量、操作手册的状态,以及排班的人性化程度所决定了。

对于大型团队而言,待命不再是非正式的人情,而成为一种基础设施。一个拥有数百项服务、数十个团队的平台,不能依赖那个恰好了解一切运作方式的人。它需要轮值制度、升级路径,以及即便原作者已经离开也依然站得住脚的准备度标准。在企业和政府场景中,风险进一步升高。受监管的服务对可用性有承诺,对操作它们的员工也负有关怀义务。一个面向公民的福利或医疗系统,不能因为唯一了解它的人正在休假就在一夜之间瘫痪。运营准备度是一个机构在发布庆典结束之后依然信守承诺的方式,而人性化的待命,则是它留住那些信守承诺之人的方式。

关键原则

  • 只在问题紧急、可采取行动且真实存在时才呼叫人。
  • 为有生活的人设计轮值安排,而不是为一台永远待命的机器设计。
  • 在服务承载生产流量之前,证明它已准备好被运营。
  • 针对用户可见的症状和 SLO 告警,而不是针对每一个内部原因告警。
  • 将操作手册和准备度评审当作会被实际使用的活文档,而不是束之高阁的归档物。
  • 谁构建了服务,谁就应在人性化且受支持的限度内参与运营它。
  • 衡量待命的健康状况,削减杂务,使负荷趋势下降而不是上升。

建议

设计人性化、可持续的轮值安排

从排班的形态入手,因为它比任何工具都更能决定可持续性。常见的模式是每周轮值,由一名主责人(primary)优先接收呼叫,一名备份人(secondary)在主责人未确认或需要帮助时提供支援。保持轮值人员池足够大,使任何一名工程师每四周待命不超过一周,理想情况下是每六周甚至更久一次。四人或更少的轮值组是一个警示信号:疾病、假期和人员流失将把它压缩成同样两个精疲力竭的英雄。

在跨时区运营的场景中,优先采用跟随太阳模型,即不同地区的团队各自负责自己的白天时段,使没有人被例行性地在凌晨 3 点呼叫。这尊重了昼夜节律,即人体内在的睡眠,觉醒周期,其被打乱是一种直接的健康代价,而非小小的不便。当”跟随太阳”不可行时,就压缩痛苦:缩短夜班时段,在糟糕的一晚之后保证恢复时间,并明确规定夜间被大量呼叫的工程师第二天早上不欠一整天的功能开发工作。

升级机制是轮值制度之下的安全网。以书面形式明确规定:当主责人在设定的时间窗口内未确认呼叫时会发生什么()先升级给备份人,再升级给团队负责人或经理,然后升级给更广泛的群体。一套自动且被充分理解的升级策略,意味着不会有任何呼叫无声无息地被漏掉,也不会有某个疲惫的人独自成为唯一的防线。

让告警策略只针对可采取行动、紧急且真实的问题

摧毁一个待命轮值制度最快的方式,就是为人们无法采取行动或无需采取行动的事情呼叫他们。采用并坚定捍卫一条规则:一次呼叫是在声称有人必须立即采取行动。如果一条告警不能同时满足三项测试()紧急、可采取行动、描述的是用户可见的真实问题()那它就不配触发呼叫。应把它路由到工单、仪表盘或每日摘要中。

这里的敌人是告警疲劳,一种有充分文献记录的现象:频繁暴露于告警中的人会变得麻木,并开始忽视告警,包括那些真正重要的告警。这是一个源自医院的患者安全概念,它原样适用于软件领域。当每一班值守都带来二十条呼叫,其中十九条是噪音时,响应者会学会半睡半醒地划掉它们,而第二十条()真正的那一条()也会得到同样条件反射式的漠视。你容忍的每一条噪音告警,都是对其他每一条告警可信度的一笔小小的税。

把告警质量当作一等的工程交付物来对待。跟踪确认到行动比率:在所有触发的呼叫中,有多少促使人做了真正重要的事情?在一个季度内从未需要任何行动的告警,是被删除或降级的候选对象。定期评审你的告警,并赋予任何工程师质疑噪音告警的权利。目标是让呼叫变得足够稀少,以至于它依然意味着什么。

针对症状和 SLO 告警,而不是针对原因

削减噪音最有效的方法,是改变你所告警的对象。针对原因告警()比如高 CPU、磁盘写满,或者单个进程重启()会为那些可能永远不会影响用户、而且系统常常能够自我修复的状况产生大量呼叫。应转而针对症状告警:服务是否在做用户需要它做的事情?把你的呼叫告警绑定到第 9.1 章定义的数字化可靠性目标()服务水平目标(SLO)()并在错误预算的消耗速度快到即将错过目标时呼叫,或者在延迟、成功率等用户可感知的指标越过一条人们真正能感受到的界线时呼叫。

这种以症状为基础、由 SLO 驱动的方法,依赖于第 9.2 章所述的可观测性和遥测数据,因为消耗速率(burn-rate)告警只有在你的指标、日志和追踪数据结构化且可信时才有效。回报是显著的:少量有意义的症状告警取代了数百条原因告警,呼叫再次与值得被叫醒的问题相关联。原因仍然重要,但它们属于响应者在症状告警触发后查阅的诊断仪表盘,而不属于呼叫路径。

要求上线前具备运营准备度

一项服务应当凭自身能力赢得进入生产环境的资格。在它承载真实流量之前,让它经历一次生产准备度评审:一次结构化的检查,理想情况下由构建团队之外的人进行,确认该服务确实可以被运营。将评审固化为一份清单,使其成为跨团队共享的标准。一份有力的清单应涵盖:监控与 SLO、符合呼叫策略的告警、仪表盘、针对可能出现的故障的操作手册、明确的归属和待命轮值、容量与负载预期、依赖和故障模式分析、备份与恢复、安全与访问控制,以及回滚计划。

这场评审是一次对话,而不是一道可以被蒙混过关的关卡。它的价值在于,它迫使构建团队在仍然掌握上下文的时候正视可运营性,而不是在六个月后凌晨两点才发现没有人写过操作手册或设置过告警。把准备度与第 9.6 章的韧性测试联系起来:一项从未在上线前注入过依赖故障的服务,是在对自己的故障方式做出一个未经检验的承诺。对于高风险的企业和政府类上线,应把准备度评审设为一个必需的、有文档记录的步骤,因为一项面向公民的服务在公开场合失败所付出的代价,既体现在金钱上,也同样体现在信任上。

编写真正会被使用的操作手册和作战手册

操作手册(runbook)是一份逐步操作文档:如何重启这项服务、如何轮换这个凭证、如何排空这个队列、如何解读这条告警。作战手册(playbook)则是针对某一类情境的更广泛应对指南。两者若无人阅读都毫无价值,而多数操作手册之所以无人阅读,是因为它们过时、含糊,或者在凌晨 3 点根本找不到。要直接解决这些失效模式。把操作手册从告警本身链接出来,让响应者一键即可到达。按照第 2.7 章推荐的文档实践,把操作手册和代码一起存放在版本控制中,使其像其他任何工件一样被评审和更新。为一个压力重重、睡眠不足的陌生人撰写它们,使用具体的命令和预期输出,而不是假定读者具备作者上下文的散文。

检验一份操作手册的标准,是除作者之外的人能否在压力下成功照做。在新人培训和演练日中验证这一点,并在某次事件暴露出它有误的那一刻立即更新它。一份撒谎的操作手册比没有还糟,因为它会自信地把一个疲惫的响应者引向错误的方向。

在人性化的限度内拥有你所构建的东西

DevOps 运动推广了”谁构建,谁运营”(you build it, you run it)的理念:编写一项服务的团队也携带它的呼叫器。这一好处是真实的,值得坚持。当构建者亲身感受到自己的呼叫时,他们会投入到可靠性建设中,修复噪音告警,并为可运营性而设计,因为反馈回路直接抵达他们本人,而不是落在一个无法修复根因的独立运维团队身上。

这一模式有你必须尊重的局限。它要求团队真正具备运营自己服务的条件:拥有相应的工具、平台、培训,以及把运营工作做好所需的时间,正如第 1.10 章的工程效能和第 1.4 章的工作方式所要求的那样。把完全的所有权强加给一个规模太小、无法组建轮值制度的团队,或者一个没有平台支持来让待命可承受的团队,是残酷的。一些组织采用混合模式:由中央 SRE 或平台团队共同拥有最艰难的层级,或者为达到高可靠性门槛的服务提供非工作时间覆盖,从而让产品团队摆脱日常的夜间呼叫。需要坚持的原则是反馈回路;其具体形态可以根据团队的规模、成熟度以及负荷的人性化程度而灵活调整。

有计划地为待命工程师安排入职培训并开展演练日

任何人都不应在第一次接过呼叫器时孤立无援、毫无准备。搭建一条入职路径:跟随一位经验丰富的响应者轮值观摩、由新人主导而导师在旁观察的”反向观摩”、逐一走查仪表盘和操作手册,以及一张清晰的升级对象地图。把”可以上待命”设为一个明确的里程碑,而不是一个默认假设。

演练日是让待命变得真实的排演。在一次演练日中,你有意制造一次故障,理想情况下在一个逼真的环境中,并让待命工程师仅使用他们在真实事件中会拥有的工具和操作手册来响应。正是在这里,你会发现操作手册已经过时、仪表盘缺少某个信号,或者告警根本没有触发。演练日建立起肌肉记忆和信心,使第一次真正的呼叫从恐慌变为流程,并自然地与第 9.6 章的混沌工程相连接。

执行干净的交接并衡量待命健康状况

班次之间的交接,是上下文最容易流失的地方。设立一次简短而结构化的交接:目前有哪些方面处于降级状态、哪些告警触发过并被抑制了、有哪些变更正在进行中、需要关注什么。配合基本的待命卫生规范,包括规定交班者不给接班者留下烂摊子,任何半途而废的问题都要被写下来。

最重要的是要衡量。你无法管理一个你看不见的负荷。跟踪每班的呼叫数、落在非工作时间(晚间、夜间、周末)的呼叫占比、确认所需时间,以及备份和升级层级被触发的频率。关注趋势而不仅仅是当前数字:一个非工作时间呼叫季度环比不断攀升的轮值制度,无论目前的绝对数字如何,都正走向职业倦怠。把这些指标输入到定期的运营评审中,由团队决定应自动化掉哪些杂务、应删除哪些告警,以及准备度在哪些方面存在不足。减少杂务()即那种随流量增长而增长、而非一次性解决的重复性手工运营工作()是让待命负荷在系统增长的同时保持平稳的方式。

权衡:优点与缺点

选择优点缺点
谁构建,谁运营紧密的可靠性反馈回路;所有者会修复根因对资源不足或规模过小的团队而言很残酷;夜间负荷不均
中央 SRE 或平台团队待命保护产品团队免受日常夜间呼叫;具备深厚的运营技能削弱构建者反馈回路;可能沦为一个倾倒场
跟随太阳轮值无人在夜间被呼叫;人性化且健康需要在多个地区配备人员;交接开销更重
小型本地轮值简单;每个人都了解系统在疾病或流失面前会崩溃;快速导致倦怠
症状与 SLO 告警呼叫少而有意义;疲劳程度低需要成熟的遥测;可能错过缓慢积累的原因
基于原因的告警能够及早且具体地发现问题淹没响应者;导致告警疲劳
严格的准备度评审生产环境中的意外惊吓更少拖慢上线速度;如果被蒙混过关会显得官僚

核心张力存在于覆盖面与人性之间。若一味追求最大覆盖面,你会得到庞大的轮值组、激进的告警和无所不在的完全所有权,这保护了系统,却磨损着人。若纯粹为响应者的舒适而优化,你则冒着让真实问题无人看管的风险。解决之道不在于折中,而在于提升质量:出色的告警、可用的操作手册和准备就绪的服务,让一个更小、更从容的轮值组也能安全地覆盖更多地盘。运营得最好的组织,通常正是那些响应者被呼叫次数最少的组织,因为他们投资的是准备度,而不是耐力。每一个用于清除一条噪音告警或修复一份操作手册的小时,都会换回多倍的人力关注,并保护整个系统的可信度。

与团队讨论的问题

  1. 你本人是否愿意承担这个轮值安排整整一年?如果答案是否定的,你会改变什么? 这个问题穿透抽象,因为它让负荷变得个人化。把真实数字带到讨论中:上个月触发了多少次呼叫,有多少落在午夜之后或周末,平均确认耗时多长。询问轮值组中的每个人,当前的形态是否是他们能够持续承受、而不会对自己的待命周心生畏惧的,并且既要听响亮的答案,也要听安静的答案。如果诚实的回答是,这个轮值制度之所以能撑下去,只是因为一两个英雄吸收了最糟糕的部分,那么你就发现了一个一旦其中一人离开就会破裂的脆弱点。你想要得到的产出是一份具体的变更清单()无论是扩大人员池、拆分为跟随太阳模式、削减夜间呼叫,还是清理告警()每一项都要有负责人和日期。

  2. 对于每一条能够呼叫人的告警,你能说出响应者应当采取的具体行动吗? 大多数轮值组从未审计过这一点,而这项练习是极具启发性的。拉出完整的呼叫告警列表,对每一条询问:它触发时响应者应该做什么,以及上个季度它触发了多少次却没有导致任何实际行动。未通过测试的告警()那些没有人能说清对应行动的告警,或者那些总是在任何人触碰之前就自行解决的告警()正是侵蚀其他所有告警可信度的噪音。如果有确认到行动的数据,就带上它,并做好大刀阔斧删除或降级的准备。目标是让每一条告警都成为对人力帮助的一次真诚请求,这次会议应当以一份比开始时更短、更精准的告警清单收尾。

  3. 当一名新工程师加入这个轮值组时,究竟是什么在为他们做准备,你测试过它是否有效吗? 待命入职培训往往被默认存在,而非被有意设计,而这个缺口会在新人第一次被独自呼叫去处理一个他们从未见过的故障时暴露出来。走查一名新响应者实际经历的路径:他们观摩了什么、阅读了哪些操作手册、是否有人最近实际按照这些操作手册操作过以确认它们依然有效,以及他们卡住时要升级给谁。可以尝试选一个真实的近期事件,问一问一名新入职者,如果仅凭当前的操作手册和仪表盘,是否能够解决它。诚实的答案通常会暴露过时的文档和缺失的信号,而这正是演练日应当在真实事件之前揭示的东西。会议结束时,应留下一个明确的待命准备度里程碑,以及一份能够持续验证它的演练日安排。

  4. 我们的非工作时间呼叫究竟落在谁身上?我们是否愿意改变人员配置或覆盖方式来保护人们的睡眠? 夜间和周末的呼叫带有一种原始呼叫计数所掩盖的健康代价,因此一个平均看起来尚可承受的轮值制度,仍可能正在悄悄压垮那几个恰好接住凌晨 3 点故障的人。带上按小时和星期几划分的呼叫分布,并按服务和响应者拆分,关注集中程度而不是均值。相互制约的考量是真实存在的:跟随太阳覆盖需要在多个地区配备人员,并增加交接开销,而小型本地轮值更简单,但会让某个人独自承担所有夜晚。要有意识地决定,解决方案究竟是增设第二地区的轮值、由中央平台团队接管非工作时间层级、缩短夜班时段并保证恢复时间,还是从源头清除产生夜间噪音的告警。对于企业和政府运营方而言,应把对待命员工的关怀义务当作一项正式义务,配上负责人和一项被报告的指标,而不是一句关于福祉的口号,因为监管机构或员工代表机构最终可能会要求你出示证明。

  5. 我们的生产准备度评审,究竟是一场关于该服务将如何失效的真诚对话,还是一份被蒙混过关的清单? 准备度评审只有在它能改变发布内容时才值得,而其失效模式,是在上线前一个下午为了满足一个没人相信的流程而随手填完的一张表格。带上最近几次已完成的评审,问一问每一次它究竟发现了什么:一份缺失的操作手册、一次未经测试的回滚、一条从未触发过的告警,还是什么都没发现。这里的张力存在于上线速度与运营严谨性之间,一场感觉像官僚程序的评审会被蒙混过关,而一场能揭示真实故障模式的评审在挽救某人的夜晚之前会一直被人反感。决定谁来主持评审、是否由构建团队之外的人主持,以及什么样的证据()比如一次被注入的依赖故障,或者一份被陌生人照做过的操作手册()才算通过。在企业和政府类上线中,把已完成的评审作为审计工件保留下来,并把它与第 9.6 章的韧性测试联系起来,因为一项面向公民的服务在公开场合失败所付出的信任代价,是任何回滚都无法挽回的。

  6. “谁构建,谁运营”在哪些地方真正对我们有利,在哪些地方对一个我们尚未配备资源的团队而言是悄然残酷的? 完全的所有权创造出让构建者去修复噪音告警、为可运营性而设计的反馈回路,但如果把它强加给一个规模太小、无法组建人性化轮值制度的团队,它就会变成一台包装成问责制的缓慢倦怠制造机。带上一张各团队拥有各自呼叫器的映射图,展示一旦剔除那些从不接高难度呼叫的人之后每个轮值组的真实规模,以及每个团队拥有哪些平台、工具和培训来把运营工作做好。这里相互拉扯的力量,存在于统一所有权这一整洁原则,与部分层级需要中央 SRE 或平台团队共同拥有最艰难的可靠性工作或提供非工作时间覆盖这一杂乱现实之间。你想要的产出,是把每项服务诚实地划分为完全自有、共同拥有或中央覆盖三类,并为任何被要求运营其无法承受之物的团队标明资源缺口。对于大型或公共部门组织,还要加上人性化所有权所假定的平台支持和人力编制的采购与招聘前置时间,因为一个你无法在相关时间窗口内配齐人手的团队,正是一个你正在把它推向失败的团队。

行业视角

初创企业。 只有几名工程师,没有空间让英雄式轮值制度隐藏问题。把稀缺的时间花在两项回报最快的改变上:删除基于原因的告警,只针对追踪核心流程的一两个 SLO 告警,并从每条剩余告警链接到一份单页操作手册。跳过精细的工具和跟随太阳模式;一份共享电子表格、一条从主责人到备份人的自动升级,以及”糟糕的一晚换来第二天早上休息”这条硬性规则,会比任何平台采购走得更远。

小型企业。 你很可能没有专职的 SRE,也无法配备夜间轮值人员,因此应更多依赖购买而非自建。优先选择托管服务和托管环境,让其提供方承担深层基础设施的呼叫,并使用托管的呼叫工具,而不是自建升级机制。把准备度设计成一份简短的清单和少数几条与客户能察觉到的事情相关联的有意义告警,并坦诚承认有些服务本来就不应在夜间呼叫人,一张早晨的工单就够了。

企业。 问题在于跨众多团队的一致性:一套共享的生产准备度评审、一套通用的呼叫策略,以及一个纳入版本控制的操作手册仓库,使一名在团队之间调动的工程师能立即理解待命体系。把待命健康状况设为受治理的指标,设定触发评审的非工作时间呼叫阈值,统一升级和交接流程,使呼叫不会无声无息地被漏掉,并让中央平台团队共同拥有最艰难的层级。像管理服务组合一样管理轮值组合,用关于杂务、呼叫负荷和倦怠风险的数据来驱动定期运营评审。

政府。 采购规则、透明度和关怀义务塑造着这种安排。把待命员工的健康状况当作一项正式的、可审计的要求,在夜间人员配置有限的地方,签约一个跟随太阳的运营合作伙伴,使没有公务员被例行性地在凌晨 3 点呼叫。把每一次已完成的准备度评审作为审计工件保留下来,编写能够被未曾构建该系统的响应者执行的操作手册,因为五年后运营它的人不会是它的作者,并在公民真正遭遇季节性高峰之前,通过演练日进行排练。

示例

初创企业。 一家十二人的初创企业推出了首款付费产品,把全部六名工程师排进一个设有主责人和备份人的每周轮值制度。第一个月里,呼叫器每晚都会响,大多是能够自行恢复的 CPU 和磁盘告警,两名工程师开始悄悄物色下家。团队停下来重建:他们删除每一条基于原因的告警,为结账和搜索定义两个 SLO,只针对错误预算消耗速率告警。呼叫数从每周约四十次降到三次。他们增加了一份每个新服务都必须通过的单页准备度清单,并把每份操作手册直接从其告警链接出来。待命从人们离职的原因变成了工作中可管理的一部分,而他们靠的是一份电子表格和纪律,而不是昂贵的工具。

企业。 一家全球支付公司在”谁构建,谁运营”模式下运营着数百项服务,由一个中央平台团队提供呼叫系统、准备度评审流程,以及一个纳入版本控制的共享操作手册仓库支撑。每项服务在上线前都要通过一次有文档记录的生产准备度评审,涵盖 SLO、告警、操作手册、容量和回滚。待命健康状况是一项被跟踪的指标:非工作时间呼叫超过阈值的团队会触发自动评审,平台团队则提供共同承担可靠性工作,直到负荷降下来。演练日每季度针对逼真的故障注入进行一次。由于标准统一、工具共享,一名工程师可以在团队之间调动并立即理解待命体系,管理层也能看到每个团队的人力负荷是否可持续。

政府。 一个国家税务机关运营着一套具有明显季节性高峰、且有法律义务面向公民保持可用的报税系统。由于其劳动力集中在一个时区,夜间人员配置有限,该机构与一家运营合作伙伴签订了跟随太阳的安排,使没有公务员被例行性地在半夜呼叫,并将待命员工的健康和关怀义务当作一项正式要求。每一次服务变更在部署前都要通过一次运营准备度评审,清单被保留用于审计。操作手册的编写方式,使其能够被未曾构建该系统的响应者执行,因为五年后运营它的人不会是编写它的人。在报税季期间,该机构针对高峰负荷场景开展演练日,使响应者在真正遭遇高峰之前先在排演中与它相遇。

商业论证:动机、投资回报率与总拥有成本

运营准备度和人性化待命的回报体现在两本账上:系统的可靠性和团队的留任率。在可靠性方面,通过了准备度评审、采用基于症状的告警的服务故障更少、恢复更快,因为操作手册确实存在、告警确实有意义、响应者也经过了排演。当呼叫抵达一个已准备就绪、并有链接操作手册的人,而不是一个茫然寻找上下文的人时,平均确认时间和平均恢复时间都会下降。在人的方面,待命是工程师流失的主要原因之一,而替换一名资深工程师的成本,是修复轮值制度所需投入的许多倍。职业倦怠,即世界卫生组织认定为一种职业现象的慢性职场耗竭状态,之所以代价高昂,正是因为它带走了你最有经验、最了解系统的人。

采纳的成本大多是一次性且适中的。你需要编写一份准备度清单,把告警从针对原因迁移到针对症状,把操作手册纳入版本控制,并建立待命健康指标。持续性的成本,是评审告警、开展演练日、恪守人性化排班的这份纪律。忽视的代价则悄然复利累积:噪音告警滋生疲劳,疲劳导致真实事件被错过和人员离职,而每一次离职都带走运营知识,进而提高留下来的人的负荷。要向领导层证明这一点,把待命健康状况与他们已经关注的指标联系起来:事件频率与持续时间、确认时间、非计划性流失,以及非工作时间呼叫的趋势。一个在系统增长的同时非工作时间呼叫却在下降的轮值制度,正是你的可靠性投资正在奏效、你的工程师明年仍会在此的直接证据。

反模式与陷阱

  • 英雄式轮值: 两三个人悄悄吸收了所有困难的呼叫,因此排班表在纸面上看起来没问题,一旦其中一人离开就会崩溃。
  • 针对原因告警: 针对 CPU、内存和磁盘而非用户可见的症状告警,用从不需要人力干预的呼叫淹没响应者。
  • 容忍告警疲劳: 已知的噪音告警被留在呼叫路径中数月之久,因为删除它们感觉有风险,直到响应者对一切都视而不见。
  • 操作手册腐烂: 上线时只写过一次的文档,从未更新,在疲惫的响应者凌晨 3 点照做时自信满满地给出错误指引。
  • 无支持的所有权: 把”谁构建,谁运营”强加给一个规模太小、无法组建轮值制度,或者缺乏平台和工具来人性化地运营它的团队。
  • 准备度作秀: 填写清单只是为了通过关卡,而不是为了真正正视服务将如何失效。
  • 上线即弃: 交付一项没有轮值、没有告警、没有操作手册的服务,然后在第一次故障中才发现这个缺口。
  • 负荷不被衡量: 没有关于每班呼叫数或非工作时间呼叫的数据,因此职业倦怠一直不可见,直到有人辞职。
  • 首次呼叫,毫无排演: 让一名新工程师在没有观摩、没有演练日的情况下上待命,然后对他们的惊慌失措感到意外。

成熟度模型

  • 第一级,启动: 待命是非正式且被动响应式的。出问题时打电话给少数几个人,告警针对原因触发且大多是噪音,操作手册缺失或过时,服务上线时没有准备度检查,也没有人衡量人力负荷,直到有人倦怠或辞职。
  • 第二级,发展: 基本实践开始出现,但因团队而异。部分轮值组已定义主责人、备份人和升级路径,部分告警得到调优,部分操作手册被编写,一份准备度清单已经存在但执行不一致。呼叫数可能只在愿意统计的团队中被记录,夜间呼叫很常见,待命入职培训是临时应变而非有意设计的。
  • 第三级,标准化: 准备度评审成为上线前有文档记录、跨团队强制执行的步骤。呼叫遵循一套通用策略,基于症状和 SLO,操作手册存放在版本控制中并从告警链接出来,入职培训包括观摩和演练日,交接遵循结构化格式,升级机制足够统一,使一名在团队之间调动的工程师能立即认出这套体系。
  • 第四级,管理: 待命被对照基准进行衡量和控制。每班呼叫数、非工作时间占比、确认时间、升级频率,以及确认到行动比率,都按团队跟踪并与目标对比,因此一个正趋向职业倦怠的轮值组,在人员辞职之前就已可见。阈值会触发评审,告警质量根据哪些呼叫导致了真实行动的证据被审计,人员配置和所有权决策由数据而非轶事驱动。
  • 第五级,编排: 待命健康是一项在整个组织中持续改进、被整合的成果。随着系统增长,呼叫和非工作时间的趋势在下降,杂务被系统性地自动化消除,“跟随太阳”或等效机制保护着睡眠,演练日和故障注入是常规操作,组织随着从每一次值班中学到的经验,不断调整所有权、覆盖方式和准备度标准,随风险图景的变化在各团队和地区之间重新平衡负荷。

讨论议题

  1. 你目前导致真实行动的呼叫与自行解决的呼叫之比是多少,要衡量它需要做些什么?
  2. 如果你最了解系统的响应者明天离职,哪些服务将变得不安全,无法再运营?为什么?
  3. “谁构建,谁运营”在哪些地方对你很有帮助,又在哪些地方对一个资源不足的团队悄然残酷?
  4. 你上一次观察一名新工程师在真实条件下照做你的某份操作手册是什么时候,当时暴露出了什么问题?
  5. 过去四个季度里,你的非工作时间呼叫是在上升还是下降?有没有人负责这个数字?
  6. 如果你严格执行准备度评审中的哪一项,本可以避免你最近一次糟糕的上线?

关键要点

  • 待命准备度在任何事件发生之前就已由你的告警、操作手册和轮值制度的质量所决定,而不是由事件发生时的英雄行为决定。
  • 只在问题紧急、可采取行动且用户可见时呼叫人;针对症状和 SLO 告警,把其余一切都路由到工单和仪表盘。
  • 为有生活的人设计轮值安排:足够大的人员池、尽可能的跟随太阳模式、自动升级,以及被兑现的恢复时间。
  • 通过生产准备度评审证明服务在上线前已准备就绪,把操作手册纳入版本控制并从告警中链接,并通过演练日排演。
  • 衡量待命健康状况,尤其是非工作时间呼叫和确认时间,并通过削减杂务和噪音、而非要求人们承受更多,来压低负荷。

参考文献与延伸阅读

  • Betsy Beyer, Chris Jones, Jennifer Petoff, and Niall Richard Murphy (eds.), Site Reliability Engineering: How Google Runs Production Systems
  • Betsy Beyer, Niall Richard Murphy, David K. Rensin, Kent Kawahara, and Stephen Thorne (eds.), The Site Reliability Workbook: Practical Ways to Implement SRE
  • Rob Ewaschuk, “My Philosophy on Alerting,” in Site Reliability Engineering appendix
  • John Allspaw and Jesse Robbins (eds.), Web Operations: Keeping the Data on Time
  • Nicole Forsgren, Jez Humble, and Gene Kim, Accelerate: The Science of Lean Software and DevOps
  • Gene Kim, Jez Humble, Patrick Debois, and John Willis, The DevOps Handbook
  • Michael T. Nygard, Release It! Design and Deploy Production-Ready Software
  • World Health Organization, ICD-11, entry on burn-out as an occupational phenomenon