3SRE 工作手册

服务等级目标

SLO 的设定与实施

SLISLOSLA错误预算策略

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第3章 服务等级目标

SLO 的设定与实施

章节导读

如果只能从整本蓝皮书中挑一章精读,大多数 Google SRE 会推荐第 3 章:服务等级目标(Service Level Objectives,SLO)。SLO 是 SRE 实践体系的中枢神经——告警基于它设计(第 4 章)、值班负载围绕它管理(第 5 章)、过载保护的阈值参考它设定(第 6 章)、发布决策由它驱动的错误预算决定(第 12 章)。没有 SLO,可靠性讨论就退化为立场之争:开发说「够稳了」,运维说「还不够稳」,谁也无法说服谁。有了 SLO,讨论就变成了数据对话:「本月错误预算还剩 30%,可以按计划发布」或者「预算已耗尽,先修复可靠性」。要理解 SLO,必须先厘清三个容易混淆的概念。SLI(Service Level Indicator,服务等级指标)是度量:一个精心选择的量化指标,反映服务的某个质量维度,比如「成功请求占总请求的比例」「99% 的请求延迟低于 300 毫秒」。SLI 本质上是一个比率:好事件数除以总事件数,取值在 0 到 1 之间。SLO(服务等级目标)是目标:对 SLI 设定的期望值,比如「可用性 SLI ≥ 99.9%」。SLO 是团队内部的工程目标,是错误预算的计算基础。SLA(Service Level Agreement,服务等级协议)是合同:与客户签订的正式协议,承诺服务水平并附带违约赔偿条款,比如「月度可用性低于 99.5% 则赔偿 10% 费用」。三者的关系是:SLI 是尺子,SLO 是刻度线,SLA 是写进合同的刻度线加上违约罚金。一个关键实践原则是:SLO 应该比 SLA 更严格。如果合同承诺 99.5%,内部 SLO 应该定在 99.9% 或更高,这样内部目标被突破时团队还有充足的缓冲时间在违反合同之前修复问题。SLO 的设定是本章的核心难点,也是大多数团队落地失败的地方。最常见的错误是「从当前性能出发」:看看系统现在跑得多好,然后把 SLO 定在略低于当前水平的位置。这种做法完全本末倒置。正确的出发点应该是用户:用户实际如何感知这个服务?用户的期望是什么?用户的客户端环境本身有多可靠?举个例子:如果你的移动 App 依赖的网络环境本身只有 99% 的可用性,那么后端 API 做到 99.99% 对用户毫无意义——用户感知的可用性上限被网络卡死在 99%。Google 的建议是把 SLO 定在「略高于用户期望、明显低于 100%」的位置,让错误预算成为团队可以主动支配的资源。设定 SLO 的具体方法论将在本章要点中详细展开,包括如何选择 SLI 的类型(可用性、延迟、质量、吞吐量、新鲜度)、如何确定聚合窗口(滚动窗口 vs 日历窗口)、如何处理多租户场景(不同客户不同标准)。错误预算策略是 SLO 从「纸面数字」变成「管理机制」的关键。仅仅设定 SLO 而不定义「预算耗尽时怎么办」,SLO 就只是一个仪表盘上的装饰。一份完整的错误预算策略需要回答:谁负责监控预算消耗?消耗速度异常时触发什么动作?预算耗尽时冻结哪些活动、豁免哪些活动?决策争议如何升级?Google 的实践中,错误预算策略是 SRE 与产品团队之间的一份「社会契约」,双方共同签署、共同遵守。当预算耗尽时,产品发布冻结,所有工程资源转向可靠性改进——这不是惩罚,而是系统自我修复的机制。本章还将讨论 SLO 的迭代。SLO 不是一次设定永久不变的,它应该随着用户期望、业务形态和系统能力的变化而调整。调整 SLO 需要谨慎:放宽 SLO 等于扩大错误预算,可能被解读为「降低标准」;收紧 SLO 则可能让团队长期处于预算耗尽状态,机制失去意义。Google 的经验是每季度回顾一次 SLO 的合理性,回顾的依据是数据:过去一个季度预算的实际消耗曲线、用户对可靠性的反馈、事故的业务影响评估。最后要强调 SLO 的文化意义。SLO 机制的深层价值是把「可靠性」从一个模糊的形容词变成了一个可测量、可管理、可交易的资源。当团队开始用错误预算思考问题时,一系列原本无解的争论都有了答案:要不要做多活架构?看预算够不够花。要不要允许每周发布三次?看预算消耗速度。要不要给这个大客户更高的保障?看差异化 SLO 的成本。这种「用数据代替直觉、用机制代替争论」的思维方式,正是 SRE 对软件工程最重要的贡献之一。接下来的要点将深入每个实践细节,代码示例会给出 SLI 计算、SLO 追踪和错误预算策略的具体实现。

核心概念

  • SLI
  • SLO
  • SLA
  • 错误预算策略

要点精析

SLI、SLO、SLA 的区别与联系:三个概念的精确辨析。这三个缩写经常被混用,但它们在 SRE 体系中的角色截然不同,混淆会导致严重的实践错误。SLI(服务等级指标)是一个测量值,本质上是一个比率:好事件数 ÷ 有效事件总数。比如「过去 30 天内,延迟低于 300ms 的请求 ÷ 全部请求 = 99.7%」。SLI 的关键在于精确定义分子和分母——什么算「好」、什么算「有效」,这些定义中的每个细节决策都会影响测量结果。SLO(服务等级目标)是对 SLI 设定的目标值:「延迟 SLI 应 ≥ 99.5%」。SLO 是内部工程目标,是团队承诺给彼此的标准,错误预算由它派生(预算 = 1 - SLO)。SLA(服务等级协议)是与客户的法律合同:「若月度可用性 < 99.5%,赔偿当月费用的 10%」。SLA 附带真实的金钱后果,因此通常比 SLO 宽松,给内部留出缓冲。三者的正确关系是:SLI 提供测量,SLO 设定内部目标(严于 SLA),SLA 承诺外部底线(宽于 SLO)。常见错误有三种:把 SLI 当 SLO 用(只有测量没有目标,仪表盘好看但不驱动任何决策);SLO 与 SLA 定成同一个数(内部目标一破就直接违约,没有缓冲);为内部系统签 SLA(内部服务用 SLO 即可,SLA 的赔偿机制在内部没有意义)。一个实用的记忆法:SLI 是温度计,SLO 是空调设定值,SLA 是你对房客承诺的「室温不会超过 28 度,否则退房租」。

如何选择 SLI:五种类型与选择原则。蓝皮书把 SLI 分为五种主要类型,每种回答不同的质量问题。可用性(Availability):服务是否可用?典型定义是成功请求 ÷ 总请求,适合无状态 API。延迟(Latency):响应是否足够快?注意延迟 SLI 的正确形式是「快于阈值的请求比例」而不是「平均延迟」——平均值会掩盖长尾,P99 延迟 5 秒但平均值 100ms 的服务对 1% 的用户来说是灾难。质量(Quality):响应内容是否完整正确?比如视频转码服务在降级模式下输出的低码率视频算「可用但质量受损」,质量 SLI 捕捉这种细微差别。吞吐量(Throughput):系统能否处理预期的工作量?适合批处理和数据管道。新鲜度(Freshness):数据是否足够新?对搜索索引、报表系统、监控数据本身至关重要——一个返回三小时前数据的股价服务,可用性 100% 也是失败的。选择 SLI 的核心原则是「从用户视角测量」:在尽可能靠近用户的位置采集数据(客户端埋点优于服务端日志,边缘节点优于中心机房),测量用户实际体验而不是系统自我感觉。另一个原则是「少而精」:每个服务选择 2 到 4 个 SLI 足够(通常是一个可用性 + 一个延迟,数据服务加新鲜度),SLI 过多会稀释注意力,让团队陷入「哪个指标都重要等于哪个都不重要」的困境。还要警惕「代理指标陷阱」:用 CPU 使用率代理负载、用队列长度代理延迟,这些原因指标可以作为诊断辅助,但绝不能作为 SLI,因为它们的涨跌与用户实际体验的相关性往往不如你想象的强。

SLO 的设定方法:从用户期望出发而非从当前性能出发。设定 SLO 是艺术与科学的结合,蓝皮书给出的方法论可以概括为四步。第一步:收集数据。测量过去 90 天 SLI 的实际分布,了解系统的「自然水平」。第二步:调研期望。三个信息源——用户合同与承诺(对外说过什么)、用户行为数据(用户在什么延迟下流失、什么错误率下投诉激增)、竞品与行业基准(同类服务的普遍水平)。第三步:评估成本。可靠性每提升一个 9,成本大约增加一个数量级:99.9% 可能只需要基本的冗余和监控,99.99% 需要多可用区部署和自动故障转移,99.999% 需要多地域多活和极其严格的变更管理。第四步:定初值并迭代。选择略高于用户最低期望、明显低于系统历史最好水平的值,先运行一个季度,根据实际数据调整。这里最重要的思维转变是:SLO 不是「系统能做到多好」的描述,而是「系统需要做到多好」的决策。定得太高(比如盲目追求 99.99%),错误预算小到一次正常发布就能耗尽,团队被迫冻结一切变更,SLO 机制名存实亡;定得太低(比如 95%),每月有 36 小时的「合法不可用」,用户早就跑光了。Google 的经验值是:大多数面向用户的服务,99.9% 到 99.99% 是合理区间;内部服务可以放宽到 99% 到 99.9%;批处理和数据管道应该用新鲜度和完整性目标而不是可用性百分比。记住 SLO 是可以修改的——它应该是团队定期审视的活文档,而不是刻在石头上的数字。

错误预算:1 - SLO 的含义与使用。错误预算是 SLO 机制的灵魂,它把「允许的不可靠程度」转化为团队可以主动支配的资源。数学上很简单:SLO 为 99.9%,错误预算就是 0.1%;在 30 天窗口内,这等于 43.2 分钟的不可用时间,或者按请求量计算的等比例失败请求。但错误预算的真正威力在于它的使用方式。首先,它授权团队「有计划地不可靠」:预算内的失败不是事故,而是系统正常运作的一部分。团队可以用预算做激进实验——金丝雀发布新版本、进行混沌测试、尝试新架构,只要消耗在预算内就是安全的。其次,它调节发布节奏:预算充足时快速迭代(每周多次发布),预算紧张时放慢脚步(加强评审、缩小发布批次),预算耗尽时冻结功能发布、全力修复可靠性。第三,它终结立场之争:当产品团队想要赶在竞争对手前发布功能时,讨论不再是「稳定重要还是速度重要」这种无解的哲学问题,而是「我们还剩多少预算、这次发布预计消耗多少」的具体计算。使用错误预算的实践细节:预算的消耗速度(burn rate)比剩余量更重要——剩余 50% 但一天内消耗了 30%,说明正在发生严重问题;预算窗口通常选 28 天(4 周整,便于对齐迭代周期)或 30 天(贴近日历月);预算状态应该对所有相关方透明可见,最好集成到发布流程中——预算不足时发布系统自动要求额外审批。Google 内部有个生动的说法:错误预算就像团队的「可靠性信用卡」,刷卡消费没问题,但刷爆了就要停止消费直到账单周期重置。

错误预算策略:预算耗尽时该做什么。错误预算策略(Error Budget Policy)是把错误预算从概念变成管理机制的关键文档,它事先约定预算处于不同状态时团队的行为规则。一份完整的策略包含五个要素。第一,监测与通报:谁负责看预算状态(通常是 SRE 值班 + 自动化报告)、多久通报一次(每周自动推送 + 异常时实时告警)、通报给谁(团队全员 + 产品负责人)。第二,分级响应:定义 2 到 4 个水位线及对应动作,典型配置是——消耗 50%:周会通报,评估近期变更的风险;消耗 80%:发布需要额外评审,暂停非关键的实验性变更;消耗 100%:冻结所有功能发布,工程资源转向可靠性改进,直到预算恢复。第三,豁免规则:明确哪些活动不受冻结限制——安全漏洞修复、旨在恢复 SLO 的可靠性改进、法律法规要求的变更、经双方负责人共同批准的特殊情况。没有豁免条款的策略会在第一次真实冲突中崩溃。第四,升级路径:当 SRE 和产品团队对「是否豁免」有分歧时,按什么路径裁决(双方负责人 → 共同上级 → 更高层),并约定裁决时限(比如 48 小时内),避免争议悬而不决。第五,复审机制:策略本身每季度复审一次,根据实际运行情况调整水位线和动作。制定策略时最容易犯的错误是「只有惩罚没有恢复」:策略详细规定了预算耗尽后冻结什么,却没说清楚如何解冻(预算随时间自然恢复?还是需要完成特定改进项?)。Google 的实践是双轨制:时间恢复(旧错误滑出窗口,预算自动回升)+ 行动恢复(完成事后分析的行动项后可以提前部分解冻),两者结合既保持了机制的严肃性,又给了团队明确的努力方向。

SLO 的迭代:如何根据实际数据调整。SLO 设定后不是一成不变的,蓝皮书强调 SLO 应该是一个持续迭代的活目标。迭代的数据来源有四类:预算消耗历史(过去几个季度预算的实际消耗曲线——如果每个季度都大量剩余,说明 SLO 定低了,可以收紧或者把富余预算用于更多实验;如果每个季度都耗尽,要么系统真的不可靠需要改进,要么 SLO 定高了需要现实一点);用户反馈信号(投诉量、流失率与 SLI 波动的相关性分析——如果发现 SLI 降到 99.5% 时投诉才明显增加,说明用户容忍度比当前 SLO 更宽);业务变化(服务从免费变收费、从内部变对外、用户群从开发者变成普通消费者,都会改变可靠性期望);系统能力变化(完成多活改造后,SLO 可以从 99.9% 提升到 99.95%,把新能力转化为对用户的承诺)。调整 SLO 的流程应该正式且透明:提出调整动议(附数据支撑)→ SRE 与产品团队共同评审 → 更新错误预算策略 → 通知所有相关方 → 设定生效日期。两个方向的调整有不同的注意事项:收紧 SLO(提高标准)相当于缩小错误预算,要评估团队是否有能力达到新标准,否则机制会立刻失效;放宽 SLO(降低标准)在组织里往往被视为「倒退」,需要谨慎沟通——正确的叙事是「把节省的可靠性成本投入到用户更在意的维度」,比如把可用性 SLO 从 99.99% 放宽到 99.95%,同时把延迟 SLO 收紧,因为数据显示用户对延迟更敏感。Google 的建议是至少每季度做一次 SLO 回顾,把它作为固定议程,而不是等问题爆发才被动调整。

多租户系统的 SLO:不同客户不同标准。当服务面向多个客户(尤其是企业客户)时,「一个 SLO 打天下」往往行不通:付费企业客户期望 99.95% 的保障,免费用户接受 99%,内部测试流量甚至不需要保障。多租户 SLO 的设计有三个层次。第一层:按客户分级设定 SLO。为不同服务等级(免费/专业/企业)定义不同的 SLO,并在 SLI 计算时按租户维度切分数据。技术上要求指标带有租户标签,能够独立计算每个租户(或每个等级)的 SLI。第二层:按请求重要性分级。同一租户内部,不同操作的重要性也不同——支付请求和心跳请求不应该用同一个 SLO 衡量。可以为关键操作定义独立的 SLI。第三层:聚合与个体的平衡。整体 SLO 掩盖个体痛苦:系统整体可用性 99.95% 达标,但某个倒霉租户可能经历了 99% 的糟糕体验。Google 的做法是同时监控「聚合 SLO」和「最差租户 SLO」,后者触发单独的告警和调查。多租户 SLO 的常见陷阱:标签基数爆炸——如果为每个租户单独计算 SLI,百万租户意味着百万时间序列,监控系统会被压垮。解决方案是按等级聚合(免费/专业/企业三条曲线)+ 对大客户单独追踪(Top 100 客户各一条曲线)+ 定期扫描长尾(离线分析找出体验最差的租户)。另一个陷阱是「降级歧视」的公平性问题:过载时应该先削减谁的流量?这需要在错误预算策略中事先约定优先级规则(通常是免费流量先降级、企业流量最后),并且规则要对客户透明,避免事故后的信任危机。

案例:Google 服务的 SLO 设定实践。蓝皮书第 3 章提供了多个真实案例,其中最有教学价值的是一个大型消费者服务的 SLO 设定过程。初始状态:该服务运行多年,从未有过正式 SLO,团队对「服务是否可靠」的判断完全靠感觉和事故数量。设定过程分四步。第一步,测量现状:团队部署了 SLI 采集,发现过去 90 天的请求成功率是 99.93%,但延迟 SLI(快于 400ms 的比例)只有 97.2%——团队一直以为自己的服务很可靠,直到开始测量延迟才发现 3% 的用户在忍受慢响应。第二步,理解用户:产品团队调取了用户行为数据,发现延迟超过 1 秒时用户放弃率显著上升,但 300ms 到 500ms 之间用户行为没有明显差异。第三步,设定初值:可用性 SLO 定为 99.9%(略低于当前水平,留出错误预算用于发布和实验),延迟 SLO 定为「95% 的请求快于 400ms」(略低于当前的 97.2%,但明确了改进方向)。第四步,运行与调整:第一个月错误预算消耗了 70%,团队紧张地检查原因,发现是一次计划内的机房迁移——这暴露了策略的空白:计划内维护是否消耗预算?讨论后决定:提前 7 天公告的维护窗口不计入 SLI,这个规则被写进了 SLI 的排除条款。这个案例的启示:SLO 设定的过程比结果更有价值——它迫使团队第一次真正测量了用户体验,第一次让工程和产品团队就「什么叫可靠」达成了精确共识,第一次有了数据驱动的发布决策依据。许多团队在设定 SLO 后惊讶地发现,他们争论多年的「稳定性问题」其实是测量缺失问题。

常见误区:SLO 设为 100%、SLO 过多、SLO 与业务脱节。蓝皮书总结了 SLO 实践中反复出现的误区,每个都值得警惕。误区一:SLO 设为 100%。「我们要做到零故障」听起来雄心勃勃,实际上是机制自杀:100% 意味着错误预算为零,任何一次失败都「违约」,团队要么长期处于违约状态麻木不仁,要么开始瞒报数据。更深层的问题是 100% 在分布式系统中物理上不可达——网络会分区、硬件会故障、软件会有 bug。Google 的立场旗帜鲜明:100% 是错误的可靠性目标。误区二:SLO 过多。有的团队为十几个指标都设定了 SLO,结果没有任何一个得到认真管理。SLO 的数量应该少到可以在一次周会上全部过完——通常每个服务 2 到 4 个。其他指标可以作为「健康信号」监控,但不配 SLO、不算预算。误区三:SLO 与业务脱节。SLO 由工程团队闭门设定,产品团队不知情不认同,结果预算耗尽要冻结发布时,产品团队跳出来反对:「凭什么你们定的数字限制我的业务?」避免方法是让产品负责人参与 SLO 设定并共同签署错误预算策略——SLO 必须是双方的契约而不是单方面的标准。误区四:把 SLO 当 KPI 考核个人。当 SLO 与绩效挂钩,人们会开始优化数字而不是优化服务:把 SLI 定义改宽松、把故障归因到「排除条款」、瞒报小事故。SLO 是团队级的工程工具,不是管理层的鞭子。误区五:只设 SLO 不建策略。仪表盘上挂着漂亮的 SLO 达成率,但预算耗尽时没有任何约定动作,SLO 沦为装饰。检验 SLO 是否真正落地的唯一标准:上一次预算紧张时,团队的发布行为有没有因此改变?

窗口选择与数据管道:滚动窗口 vs 日历窗口。SLO 的计算必须指定时间窗口,窗口选择影响预算的行为模式。滚动窗口(rolling window):SLI 基于「过去 N 天」的连续数据计算,每时每刻都在更新。优点是平滑——一次事故的坏数据会随着时间逐渐滑出窗口,预算自动渐进恢复;缺点是计算成本高(需要保留窗口内全部数据)且「预算恢复时间」不直观。日历窗口(calendar window):按自然月(或周)计算,每月一日预算重置。优点是简单直观、便于对齐业务周期和财务结算(SLA 通常按日历月);缺点是悬崖效应——月底预算耗尽的团队熬过几天就满血复活,可能诱发「月底躺平」;且月初的一次大事故会困扰整个月。Google 的实践是两者结合:内部 SLO 管理用滚动窗口(平滑、真实反映近期状态),对外 SLA 计算用日历窗口(合同要求)。实现层面还有几个细节:窗口长度常用 28 天(4 周整)或 30 天(近似月);短窗口(如 1 小时)用于快速告警但不用于预算管理;数据缺失的处理要事先约定——监控系统自身故障的时段,SLI 算好还是算坏?Google 的建议是保守处理:无法证明是好的就算坏的,这同时给了监控团队保持自身可靠的压力。数据管道的可靠性直接影响 SLO 的可信度:如果 SLI 计算依赖的日志管道延迟或丢数据,预算数字就会失真。因此成熟的 SLO 实现会为 SLI 数据管道本身设定新鲜度和完整性目标——测量系统的可靠性也需要被测量,这是第 7 章数据管道主题的伏笔。

代码示例

/* 示例 1:SLI 规范文档模板(YAML) */
sli_spec:
  name: checkout-api-availability
  service: checkout-api
  type: availability
  definition:
    numerator: "返回非 5xx 状态码且延迟 < 2s 的请求数"
    denominator: "全部有效请求数"
  data_source:
    system: prometheus
    metric: http_server_requests_total
    labels: { job: "checkout-api" }
  exclusions:
    - "健康检查路径 /healthz 与 /readyz"
    - "内部压测流量(header: x-load-test=true)"
    - "已公告的计划内维护窗口"
  aggregation: "30 天滚动窗口"
  slo_target: 0.999
  owner: sre-checkout@company.com
  review_cadence: quarterly
这份 YAML 展示了工业级 SLI 规范应有的完整要素。最容易被忽视但最重要的是 exclusions(排除规则):健康检查流量通常每秒多次且永远成功,不排除会稀释真实用户的失败率;压测流量会人为制造大量「失败」;计划内维护是否计入预算必须事先约定,否则第一次维护就会引发争议。data_source 部分把 SLI 锚定到具体的指标和标签,避免「同一个 SLI 不同人算出不同数字」的窘境。owner 和 review_cadence 把 SLI 变成有人负责、定期维护的活文档。建议把所有服务的 SLI 规范集中存放在一个 Git 仓库中,变更走代码评审流程——SLI 定义的修改本质上是在修改「成功的定义」,其严肃性不亚于修改计费逻辑。
/* 示例 2:延迟 SLI 的 PromQL 实现 */
/* 延迟 SLI:快于 300ms 的请求比例(30 天滚动窗口) */
sum(rate(http_request_duration_seconds_bucket{job="api",le="0.3"}[30d]))
/
sum(rate(http_request_duration_seconds_count{job="api"}[30d]))
延迟 SLI 的正确实现依赖 histogram 类型指标:分子是 le="0.3" 桶的累积计数(所有快于 300ms 的请求),分母是总请求数。两个关键细节:第一,必须用 _bucket 的 le 标签做「快于阈值」的判断,而不是用 histogram_quantile 计算 P99——「99% 的请求快于 300ms」和「P99 延迟是 300ms」数学上等价,但前者天然是一个 0 到 1 的比率,与其他 SLI 形式统一,便于错误预算计算;第二,le 桶的边界要在指标采集时规划好,如果最接近的桶是 le="0.25" 和 le="0.5",你就无法精确计算 300ms 阈值,只能近似。这提醒我们:SLI 设计要先行,监控埋点要为 SLI 服务,而不是反过来「有什么指标就凑合用什么」。生产环境中 30d 窗口的 rate 计算开销较大,应该用 recording rule 每小时预聚合一次,SLO 仪表盘查询预聚合结果。
/* 示例 3:错误预算燃烧率(burn rate)计算 */
/* 燃烧率 = 当前错误率 / 预算允许的错误率
   燃烧率 1 = 恰好按 SLO 速度消耗预算
   燃烧率 14.4 = 一小时消耗掉 2% 的 30 天预算 */
(
  1 - (
    sum(rate(http_requests_total{job="api",code!~"5.."}[1h]))
    /
    sum(rate(http_requests_total{job="api"}[1h]))
  )
)
/ (1 - 0.999)
燃烧率是错误预算管理中最灵敏的指标,也是第 4 章多窗口多燃烧率告警的核心输入。理解燃烧率的量级很重要:对于 SLO=99.9%、窗口 30 天的服务,燃烧率 1 意味着 30 天恰好耗尽预算;燃烧率 14.4 意味着 2 天耗尽;燃烧率 144 意味着 5 小时耗尽。燃烧率告警的逻辑是「按消耗速度分级响应」:高速燃烧(如 14.4 倍)说明正在发生严重事故,需要立即叫醒值班;低速燃烧(如 1 倍)说明系统处于 SLO 边缘的亚健康状态,工作时间处理即可。注意这个查询用了 1 小时短窗口——短窗口灵敏但易受噪音影响(一次部署的瞬时错误可能触发误报),所以生产实践中总是「长窗口确认 + 短窗口加速」组合使用:只有当 1 小时和 5 分钟窗口的燃烧率都超标时才告警,既灵敏又稳健。这个组合技巧将在第 4 章展开为完整的告警体系。
/* 示例 4:SLO 追踪的 recording rules(Prometheus) */
groups:
  - name: slo-checkout-api
    interval: 1m
    rules:
      - record: slo:http_requests:ratio_rate1m
        expr: |
          sum(rate(http_requests_total{job="checkout-api",code!~"5.."}[1m]))
          /
          sum(rate(http_requests_total{job="checkout-api"}[1m]))
      - record: slo:http_requests:ratio_rate5m
        expr: |
          sum(rate(http_requests_total{job="checkout-api",code!~"5.."}[5m]))
          /
          sum(rate(http_requests_total{job="checkout-api"}[5m]))
      - record: slo:http_requests:ratio_rate30m
        expr: |
          sum(rate(http_requests_total{job="checkout-api",code!~"5.."}[30m]))
          /
          sum(rate(http_requests_total{job="checkout-api"}[30m]))
      - record: slo:error_budget_remaining:ratio
        expr: |
          1 - (
            (1 - sum(rate(http_requests_total{job="checkout-api",code!~"5.."}[30d]))
              / sum(rate(http_requests_total{job="checkout-api"}[30d])))
            / (1 - 0.999)
          )
这组 recording rules 是 SLO 工程化的标准配置。前三条以不同时间尺度(1m、5m、30m)预计算成功率,供多窗口燃烧率告警使用——告警规则直接引用这些预聚合结果,避免每次评估都扫描原始数据。第四条计算错误预算剩余比例:0.5 表示还剩一半预算,0 表示耗尽,负数表示超标。命名遵循 Prometheus 社区约定(level:metric:operations 格式),让规则可读可维护。interval: 1m 意味着每分钟重算一次,对预算管理足够(预算是 30 天尺度的量,分钟级刷新已经很及时)。部署这组规则后,配合 Grafana 仪表盘展示三条曲线:当前成功率(分钟级波动)、30 天滚动成功率(与 SLO 线对比)、预算剩余比例(趋势与水位),团队就能对 SLO 状态一目了然。这套配置可以直接用 Sloth 等工具自动生成,但手写一遍有助于理解每个数字的来源。
/* 示例 5:错误预算策略的机器可读配置 */
error_budget_policy:
  service: checkout-api
  slo: 0.999
  window: 30d
  levels:
    - name: normal
      condition: "consumed < 0.5"
      actions: ["正常发布节奏", "周报同步预算状态"]
    - name: caution
      condition: "0.5 <= consumed < 0.8"
      actions: ["发布前检查预算状态", "高风险变更需 SRE 评审"]
    - name: critical
      condition: "0.8 <= consumed < 1.0"
      actions: ["仅允许低风险发布", "启动可靠性专项排查"]
    - name: exhausted
      condition: "consumed >= 1.0"
      actions:
        - "冻结全部功能发布"
        - "工程资源转向可靠性修复"
        - "每日站会追踪预算恢复进度"
  exemptions:
    - "安全漏洞修复(CVE 或内部安全团队认定)"
    - "直接改善 SLO 的可靠性变更"
    - "SRE 负责人与产品负责人联合批准的例外"
  unfreeze:
    time_based: "旧错误滑出 30 天窗口,预算自然恢复至 consumed < 0.8"
    action_based: "完成事故行动项并经联合评审后可提前解冻"
这份配置把错误预算策略表达为机器可读、可自动执行的形式,比纯文档更进一步。四个水位等级(normal/caution/critical/exhausted)对应渐进式响应,避免了「正常」到「冻结」的二元跳变。exemptions 的三条豁免各有深意:安全修复永远优先(不能因为预算冻结而带着已知漏洞运行);可靠性变更豁免打破了「越不可靠越不能改」的死循环;联合批准条款保留了人的判断空间但要求双方共识。unfreeze 部分的双轨解冻机制值得注意:时间解冻是自动的(滚动窗口的数学性质),行动解冻是激励性的(完成改进可以提前恢复发布权),两者结合让冻结期成为改进期而不是单纯的惩罚期。落地时可以把这份配置接入发布系统:CI/CD 流水线在部署前查询预算状态,exhausted 级别自动阻断非豁免发布——把策略从「约定」升级为「强制」,这是错误预算机制成熟的标志。

实验笔记

本实验的目标是为一个真实服务完整设计 SLI/SLO 体系并制定错误预算策略。实验分六个部分,预计 5 到 6 小时,建议 2 到 4 人小组完成,一人扮演 SRE、一人扮演产品负责人,角色对立能让讨论更真实。第一部分:用户旅程梳理(约 45 分钟)。列出服务的三个最重要用户旅程(例如电商的「浏览商品」「搜索」「下单支付」)。对每个旅程回答:用户发起的请求是什么?成功的定义是什么(HTTP 200 就算成功吗?返回空结果算吗?)?用户能容忍的最长等待时间是多少?旅程中哪些步骤失败用户会立刻察觉、哪些可以容忍?产出:每个旅程一张「成功/失败判定表」。检查清单:是否区分了「技术成功」和「业务成功」?是否考虑了客户端缓存导致的请求缺失?第二部分:SLI 规范撰写(约 1 小时)。为每个用户旅程定义 SLI,写成精确的规范文档:SLI 名称、类型(可用性/延迟/质量)、分子定义(什么算好事件)、分母定义(什么算有效事件)、数据来源(哪个指标、哪个日志字段)、聚合方式、排除规则(健康检查、内部流量、爬虫是否排除)。至少定义一个可用性 SLI 和一个延迟 SLI。常见陷阱提醒:分母为零的时段如何处理?重试请求算一次还是多次?CDN 缓存命中的请求是否计入?把每个决策的理由写下来。第三部分:SLO 设定决策(约 1 小时)。使用决策框架为每个 SLI 设定 SLO:(1) 查历史数据:过去 90 天 SLI 的实际分布是多少?(2) 问用户期望:用户合同、竞品水平、用户投诉阈值分别指向什么数字?(3) 评估成本:达到 99.9% 和 99.99% 分别需要什么架构投入?(4) 定初值:选择「历史 P50 水平附近、略高于用户最低期望」的值作为起点。为每个 SLO 写明窗口(建议 30 天滚动)和设定理由。特别练习:你的服务过去 90 天可用性是 99.95%,产品负责人要求定 99.99%「显得专业」,你如何回应?用错误预算的计算说服对方:99.99% 意味着每月只有 4.3 分钟预算,而历史上平均每月有 22 分钟不可用,这个 SLO 从第一天起就是失败的。第四部分:错误预算策略制定(约 1 小时)。起草策略文档:预算消耗的通报机制(每周自动报告给谁);分级响应(消耗 50% → 周会通报;消耗 80% → 收紧发布评审;消耗 100% → 冻结功能发布);豁免清单(安全修复、可靠性修复、法定要求);争议升级路径(SRE 负责人与产品负责人共同裁决,再升级到双方上级);策略复审周期(每季度)。写完后做压力测试:构造三个场景检验策略是否有漏洞——「预算耗尽当天发现严重安全漏洞」「预算耗尽但竞争对手发布重大功能」「一次第三方故障消耗了全部预算」。第五部分:用 Prometheus 实现追踪(约 1 小时)。在实验环境中部署 Prometheus,为服务(可用 mock 服务生成指标)编写 recording rules 计算 SLI,用 PromQL 表达错误预算消耗比例,配置一条「预算消耗超过 50%」的告警规则,在 Grafana 中建立 SLO 仪表盘(当前 SLI 值、预算剩余、消耗趋势三条曲线)。第六部分:评审与答辩(约 45 分钟)。小组间互评:SLI 规范是否有歧义?SLO 设定的理由是否充分?策略在压力场景下是否可执行?每个小组必须回答质询问题:「如果下个月预算意外耗尽,你们的第一动作是什么?」通过完整走一遍这个流程,你会发现 SLO 设计的难点从来不是数学,而是定义「什么算好」时的无数细节决策——这正是本章反复强调「从用户视角出发」的原因。

延伸阅读

  • The Site Reliability Workbook 第 3 章 "Implementing SLOs"——本章原始出处,包含 Google 及多个外部公司的 SLO 实施案例,详细讨论了 SLI 选择的决策流程、窗口设计、多租户 SLO 和错误预算策略模板。原文的案例研究部分展示了不同行业(金融、电商、云服务)如何裁剪 SLO 实践,值得对照自己的业务阅读。
  • SRE 黑皮书第 4 章 "Service Level Objectives"——SLO 概念的经典阐述,定义了 SLI/SLO/SLA 三者的关系,介绍了「用户期望管理」和「错误预算」的原始思想。黑皮书讲原理,蓝皮书讲操作,两章对照阅读效果最佳。
  • Implementing Service Level Objectives(Alex Hidalgo 著)——整本书专注 SLO 实施,比蓝皮书第 3 章更细致:如何用 Sloth 工具声明式定义 SLO、如何处理数据缺失、如何向管理层汇报 SLO 状态。书中「SLO 不是 KPI」的讨论对避免 SLO 被滥用为绩效考核工具很有启发。
  • The Art of SLO 课程材料(GitHub: captn3m0/google-sre-ebook 及 slo-tools 相关仓库)——Google 官方 SLO 培训课程的幻灯片和练习,包含大量互动式案例讨论,如「为 Gmail 设计 SLO」「为支付系统设计 SLO」。适合作为团队内训材料,两小时的 workshop 就能让全员建立 SLO 共识。
  • Sloth(github.com/slok/sloth)——开源的 SLO 即代码工具,用 YAML 声明 SLI/SLO,自动生成 Prometheus recording rules 和多窗口多燃烧率告警。它是把本章方法论工程化的最佳起点,README 中的示例覆盖了可用性、延迟等多种 SLI 类型。
  • Google Cloud Architecture Framework: SLO 设计指南——Google Cloud 官方文档中关于 SLO 设计的章节,提供了面向云服务消费者的实践建议,包括如何为 Serverless、托管服务设定 SLO(当你无法控制底层时,SLI 应该在哪里测量)。
  • OpenSLO 规范(openslo.com)——由 Dynatrace、Google、Microsoft 等公司推动的 SLO 定义开放标准,目标是用统一的 YAML 规范描述 SLO,实现跨工具互操作。关注这个规范有助于避免被单一监控厂商锁定,也代表了 SLO 工具化的行业方向。`, 《为什么 100% 可用性是错误的目标》——Google Cloud 架构师团队的经典博文,用家庭网络可用性的实测数据论证了「用户端可靠性天花板」的概念,是说服管理层接受「不完美 SLO」的最有力材料,全文短小精悍,适合转发。
3/12服务等级
0%