Skip to content

SLO 与错误预算实战:把可靠性目标变成可执行的发布闸门

运维和产品之间永远有一场拉锯:产品想更快发版,运维想少做变更,因为变更就是故障的来源。没有统一口径时,每次“这次到底发不发”都靠嗓门大或谁刚被半夜叫醒决定。服务等级目标(SLO)和它的错误预算,就是把这场扯皮变成提前约定好的算术。本文面向已经在做监控、但还没把 SLO 真正落成发布规则的团队,给一套从定义到落地再到告警的实操链路。

1. 先厘清三个词:SLI、SLO、SLA

这是最容易混的一层,先把术语钉死:

  • SLI(服务等级指标):用户实际体验的量化测量,通常是一个比值,比如“成功请求数 ÷ 有效请求数”“0.5 秒内完成的请求比例”。
  • SLO(服务等级目标):给 SLI 定的窗口内目标,比如“滚动 30 天里 99.9% 的请求成功”。
  • 错误预算:SLO 的补集,即目标允许失败的额度(1 − SLO)。99.9% 的 SLO 意味着 0.1% 的失败额度。
  • SLA(服务等级协议):对客户的外包合同,违约通常要赔钱。

关键纪律:SLO 永远比 SLA 收紧一档。比如对外 SLA 是 99.5%,内部 SLO 就定 99.9%。这样内部预算先烧光、行为先改变,给团队在客户能索赔前留出修正空间。把内部 SLO 设得比外部 SLA 松,等于让预算机制失效。

2. 选一个用户导向的 SLI

SLI 要从“用户能感知”的地方量,越靠近用户越好(负载均衡器或客户端,而不是服务内部深处)。按服务类型匹配:

  • 请求/响应类 API:可用性(非 5xx 比例)、延迟(快于阈值的请求比例)。
  • 数据管道:新鲜度(N 分钟内更新的记录比例)、正确率。
  • 存储:持久性、读写延迟。
  • 批处理:在截止时间前成功完成的任务比例。

不要把 SLI 绑在“服务器 CPU 正常”这类用户无感的指标上——服务健康不代表关键动作能成功。

3. 定一个“测得出”的 SLO

拍脑袋写“三个九”是最常见的坑,目标要么永远碰不到、要么月月耗尽。五步法:

  1. 挑两三个最重要的用户旅程(登录、搜索、下单)。
  2. 选匹配的 SLI 类型。
  3. 先采集四周基线,目标略低于常态表现。
  4. 把维护窗口、重试、部分失败怎么算写清楚。
  5. 季度复盘,按预算消耗情况收紧或放宽。

目标必须能被两个人用同一份遥测复现,否则没法做一致的发布决策。

4. 错误预算怎么算:时间制 vs 请求制

时间制把预算表达为“允许宕机多少分钟”:99.9% 月度 ≈ 43.2 分钟。但它对凌晨低峰和高峰一视同仁,不公平。请求制表达为“允许多少笔失败请求”,高峰宕机自然消耗更多,更贴合业务影响。PromQL 示例(假设 0.5 秒阈值桶):

sum(rate(http_request_duration_seconds_bucket{route="/checkout", le="0.5"}[30d]))
/
sum(rate(http_request_duration_seconds_count{route="/checkout"}[30d]))
前提是有能区分有效请求和好请求的埋点。纯在线 API 优先用请求制,批处理/可达性类用时间制也成立。

5. 燃烧率告警:把滞后指标变领先指标

普通告警是“已经跌破 99.9% 才叫”,往往来不及。燃烧率告警盯消耗速度:1 倍燃烧率 = 当前速度刚好在窗口结束耗尽,2 倍 = 一半时间耗尽。14 天窗口配 2 倍燃烧率,约一周就能拉响。实战用多窗口多燃烧率组合过滤抖动:

# 快速窗口高燃烧率 + 慢窗口确认
# 1h 窗口 14.4 倍,6h 窗口 6 倍,同时满足才告警
它能比单纯盯 SLI 百分比早得多发现风险。

6. 把预算写成发布闸门

这是错误预算策略的核心——把剩余预算切成几档,每档写明发布姿态和决策人:

  • > 50%:正常发版,跑实验、做风险迁移。
  • 25%–50%:谨慎,加强评审。
  • 0%–25%:受限,暂停非必要功能发版。
  • = 0%:耗尽,暂停变更、转做可靠性,安全修复走例外。

例外流程必须提前定义:谁审批、记录什么、何时恢复。把决策在平静时由没被压力左右的人定好,正是这套机制的价值。

7. 上线后的巡检与防退化纪律

SLO 体系会悄悄退化:SLI 埋点被改坏导致预算失真、阈值半年没复盘变成摆设、例外被滥用成常态。建立纪律:

  • 每日:看燃烧率看板和剩余预算,关注是否进入受限档。
  • 每周:对进入谨慎/受限档的服务做复盘,分配可靠性工作。
  • 每变更前:确认 SLI 埋点和口径没动,预算计算结果可信。
  • 每季度:重新评估目标,按真实消耗收紧或放宽。
  • 红线:禁止把 SLA 当成“唯一算数的承诺”而忽视内部预算;禁止例外流程无审批无记录;禁止 SLI 口径被偷偷改宽来“美化”预算。

FAQ

SLI、SLO、SLA 三个词到底怎么区分,老搞混? 一句话链条:SLI 是尺子,SLO 是目标,SLA 是对外的合同。SLI(服务等级指标)是“用户实际体验的量化测量”,比如成功请求数÷有效请求数;SLO(服务等级目标)是“给 SLI 定的窗口内目标”,比如 30 天里 99.9% 请求成功;错误预算是 SLO 的补集(1−SLO),即允许失败的量;SLA 是对客户承诺、违约要赔钱的合同。关键纪律是 SLO 永远比 SLA 收紧一档——这样内部预算先烧光、行为先改变,给团队在客户索赔前留出修正空间。混淆两者的危害是:一旦只把 SLA 当“唯一算数的承诺”,内部预算烧光看起来也无所谓,等客户能索赔时差距已经合拢。 怎么定一个“测得出”的 SLO,而不是拍脑袋写三个九? 五步走,且必须能复现。第一,挑两三个对用户和营收最重要的用户旅程(登录、搜索、下单),从用户动作出发,不从服务器出发。第二,选匹配的 SLI 类型:可用性看非 5xx 比例,延迟看“快于阈值的请求比例”,数据管道看新鲜度。第三,先采集四周真实 SLI 基线,目标就定在略低于常态表现的位置,这样团队才有预算可花。第四,把维护窗口、重试、部分失败怎么算写清楚,免得事后扯皮。第五,按季度复盘:预算从来不碰就收紧,月月冻结就放宽或补可靠性投入。目标必须从“用户能感知”和“今天能做到”两个锚点出发,否则预算只是个好看的数字。 错误预算到底按时间算还是按请求算,哪个更公平? 优先按请求算,更公平。时间制把预算表达为“允许宕机多少分钟”(99.9% 月度≈43.2 分钟),但凌晨低谷的宕机和中午高峰的宕机消耗一样多,对业务不公平。请求制把预算表达为“允许多少笔失败请求”,高峰宕机自然消耗更多、低峰更少,更贴合真实影响。PromQL 里用 good÷valid 的比值直接得出,例如把 le="0.5" 桶的命中数除以总计数,得到“0.5 秒内完成的比例”。前提是你得有能区分有效请求和好请求的指标埋点。具体怎么选看你的服务形态:纯在线 API 用请求制,批处理/可达性类用时间制都行。 错误预算快烧光了,到底要不要发版,谁来拍板? 这正是错误预算策略要提前回答的问题,而不是出事时现吵。把剩余预算切成几档:50% 以上正常、25%–50% 谨慎(加强评审)、0%–25% 受限(暂停非必要发版)、0% 及以下耗尽(暂停变更、转做可靠性)。每档写明“发布姿态”和“谁有决定权”。耗尽时不是一切停摆:安全修复、恢复性变更可以走约定的例外流程,由指定审批人签字并记录。把决策权在平静时、由没被压力左右的人提前定好,正是这套机制的价值——它等价于“大促前的代码冻结”,承诺在双方都冷静时最有约束力。 燃烧率(burn rate)告警和普通的“可用率跌到 99.9% 以下”告警有什么区别? 普通告警是“已经跌破阈值才叫”,往往来不及;燃烧率告警盯的是“消耗速度”,能在预算还没烧光时就预警。比如 99.9% 目标的 1 倍燃烧率意味着按当前速度刚好在窗口结束时耗尽,2 倍意味着一半时间就耗尽,14 天窗口配 2 倍燃烧率告警就能在约一周时拉响。实战上用多窗口多燃烧率组合(如 1h 窗口 14.4 倍 + 6h 窗口 6 倍)过滤抖动、减少误报。它是把“预算消耗”从滞后指标变成领先指标的关键手段,比单纯盯 SLI 百分比更早发现风险。

相关文章