SLO 工程:错误预算、Burn Rate、多窗口多燃烧率告警
某团队定了 99.9% 可用性 SLO——一年 8.76 小时错误预算。双十一前一天,他们用完了全部预算。不是被一个灾难性事故一次消耗的——是被过去三个月 12 次”小发布”累积消耗的——每次发布引入了一个微小的延迟退化(p99 从 120ms 升到 130ms),每次都没到告警阈值,每次都没人注意到 SLO 面板上的那条预算线在悄悄往下走。
这个故事概括了 SLO 工程的核心挑战:定一个数字很容易,让这个数字驱动日常决策很难。SLO 的价值不在数字本身,在于它创建了一条从”业务可接受的不可用程度”到”工程团队每天的开发节奏”的完整决策链。
一、SLO 的概念框架
SLI(Service Level Indicator):实际测量的指标值。例如”过去 5 分钟滚动窗口中,checkout 服务的请求成功率是 99.93%“。
SLO(Service Level Objective):SLI 需要满足的目标范围。例如”30 天滚动窗口内 checkout 服务的请求成功率必须 ≥ 99.9%“。
SLA(Service Level Agreement):违反 SLO 的合同后果,通常涉及赔偿。SLA 比 SLO 更宽松——合同会给自己留余地。如果 SLO 是 99.9%,SLA 可能是 99.5%——“如果连这个都达不到,我们赔钱”。
错误预算(Error Budget):1 − SLO = 允许的最大不可用量。99.9% → 月错误预算 = 30 × 24 × 60 × 0.001 = 43.2 分钟。这个 43.2 分钟不是你用来”消耗”的——它是你用来做出策略决策的:预算 > 50% 正常发布,预算 20–50% 冻结 feature 发布,预算 < 20% 全团队只做可靠性改进。
二、SLI 的选择与定义
一个服务只需要 2–4 个 SLI。太多的 SLI 和没有 SLI 是一样的效果——没人能同时关注 20 个指标。常见的 SLI 类型:
- 可用性:成功请求 / 总请求 ≥ 99.9%(排除 429 rate limit——这不是服务故障)
- 延迟:p99 延迟 < 阈值(如 200ms)。用 p99 而不是平均——平均会把尾部延迟平滑掉
- 吞吐:QPS ≥ 某个值(通常用于批处理系统而非实时 API)
- 持久性:数据写入后不丢失的比例(存储类服务)
SLI 的测量窗口选择直接影响告警的准确性和噪音。1 分钟窗口:噪声大(每次 GC 暂停都可能触发),频繁误报。5 分钟窗口:是一个较好的平衡——大多数 SRE 团队采用这个窗口。1 小时窗口:反应太慢——问题发生 1 小时后才触发告警。
三、错误预算的工程计算
错误预算公式:预算 = (1 − SLO) × 时间窗口内总请求数。可消耗的失败请求
= 总请求 × (1 − SLO)。实际消耗 =
count of failed requests。
错误预算的烧钱速度(Burn
Rate):已消耗预算 / 预期正常消耗。如果过去 1
小时内你用掉了 2% 的月预算,你的 Burn Rate =
2% / (1/720) ≈ 14.4x——你以正常速度的 14.4
倍在烧钱。
Prometheus 中的烧钱速度计算用 Recording Rule 实现:
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
(sum(rate(http_requests_total[5m])) * (1 - 0.999))
四、多窗口多燃烧率告警
Google SRE Book 第 5 章提出了一套经过验证的告警策略:
- 短窗口(1h)+ 高燃烧率(14.4x):1 小时内烧掉 2% 的月预算 → 紧急 Page。用了 1 小时时间窗口和 14.4 倍燃烧率——确保误报率足够低。
- 长窗口(6h)+ 低燃烧率(1x):6 小时内烧掉 10% 的月预算 → Ticket/Warning 告警。这个窗口更长、燃烧率更低——过滤掉噪声但保留了对持续退化趋势的感知。
PromQL 实现(短窗口):
(
sum(rate(http_requests_total{status=~"5.."}[1h]))
/
sum(rate(http_requests_total[1h]))
)
> 14.4 * (1 - 0.999)
这个公式的直觉是:正常消耗速度是
(1−SLO)。如果实际消耗速度超过正常速度的 14.4
倍——说明当前在严重加速烧预算。
五、SLO 文化的落地
定 SLO 数字是最简单的部分。最难的三个部分是:
与业务对齐 SLI。技术团队准备的 SLI 候选(“p99 latency of checkout API”),产品/业务团队确认”这个指标的哪些取值范围对应’用户感觉服务正常’“。如果产品团队说”p99 延迟 < 200ms 用户无感,> 500ms 用户开始投诉”,那你的 SLO 阈值就有了业务锚点。
SLO Dashboard 不是给 SRE 看的。是给 PM 和 TL 看的——一眼看到”这个月还剩多少预算”、“下个版本还能不能正常发”。如果 PM 从来不打开这个 Dashboard,SLO 就没有发挥控制发布节奏的作用。
每月的 SLO 评审会。回顾 SLI 采集质量(数据本身有没有断?)、SLO 达标情况(超预算了吗?因为什么?)、错误预算策略是否需要调整(SLO 定太松还是太紧?)。
六、关键概念回顾
- SLI → SLO → SLA:测量 → 目标 → 合同。不要混用这三个概念。
- 错误预算:
1 − SLO。不是”可浪费量”,是”发布节奏控制器”。 - Burn Rate:预算消耗速度与正常速度的比值。14.4x 短窗口 + 1x 长窗口的告警组合。
- SLO 的核心价值:把”我们该不该暂停发布”从一个主观判断变成一个有数据支撑的自动决策。
七、工程坑点
SLO 数字的选择不计算预算。99.9% vs 99.99%——差一个 9,预算差 10 倍。选 SLO 之前先手动算一遍”这意味着每月可以有多长时间服务不正常”。
不同类型的错误混在一起算 SLI。429(rate limit)不是服务器故障——是客户端频率控制。500(server error)是真正的故障。把 429 和 500 混在一起会让错误预算被客户端滥用消耗掉。
监测数据在故障期间也断了。如果你的 Prometheus 在事故中和业务服务一起挂了——你的 SLI 采集也停了。“不知道自己有没有超预算”——这是最危险的盲区。
八、下一步
SLO 定好之后,需要一套告警体系来承载 Burn Rate 告警——从 Alertmanager 规则引擎到 PagerDuty 排班,再到告警分级与抑制。下一篇 告警体系:Alertmanager、PagerDuty、分级抑制。
上一篇:内核追踪:ftrace、kprobe、uprobe、tracepoint 生产实战
下一篇:告警体系:Alertmanager、PagerDuty、分级抑制
参考资料
- Google, Site Reliability Engineering, Chapters 4-5, O’Reilly, 2016
- Google, The Site Reliability Workbook, Chapter 2: Implementing SLOs, O’Reilly, 2018
- Prometheus, Alerting Rules, https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【可观测性工程】告警体系:Alertmanager、PagerDuty、OnCall 与分级抑制
建一套不让人崩溃的告警体系。从 Prometheus Alertmanager 的分组/抑制/静默三元组,到 PagerDuty 排班与升级策略,到分级告警的设计模板与告警质量持续治理。
【系统架构设计】SLO 工程:可靠性的量化管理
SLI、SLO、SLA 不只是运维指标——它们是架构决策的定量依据。本文从 Google SRE 的 Error Budget 策略出发,拆解多窗口燃烧率告警的数学原理,讲清楚 SLO 如何在产品与工程的冲突中充当仲裁者,并给出基于 Prometheus 和 Grafana 的落地方案。
可观测性工程
从 Metrics、Logs、Traces 到 Profiling、eBPF、OpenTelemetry 与 SLO 治理,面向中国工程团队的可观测性系统化手册。全 25 篇。
【可观测性工程】指标体系设计:USE、RED、Golden Signals 与业务 KPI
USE 方法论适用于资源,RED 方法论适用于请求,Golden Signals 适用于服务——三套方法论各有其适用对象。本文从 Brendan Gregg、Tom Wilkie、Google SRE 的原始定义出发,构建覆盖资源→服务→业务的完整指标体系,并给出 Prometheus 命名规范、基数治理策略与可抄的指标清单。