SLO/SLI 落地与错误预算治理实践
"可靠性 99.9%"如果只是指标墙上的数字,那它毫无意义。Google SRE 方法论的核心是把它变成可执行的管理机制:定义 SLI(服务指标)、设定 SLO(服务目标)、用**错误预算(Error Budget)**把"可用性"换算成可决策的余额,再决定何时该修故障、何时该放行新功能。
第一步:选对 SLI
SLI 是"我们实际测量的指标",通常从可用性、延迟、吞吐、错误率四类里选。好的 SLI 要贴近用户可感知的体验:对网站来说,常见口径是"有效请求中成功占比"与"P95 延迟"。注意两点:
- 口径要精确:例如"错误"应明确定义为 HTTP 4xx/5xx 中的哪几类、"有效请求"是否排除爬虫与健康检查。
- 用比率而非绝对值:SLI 以"好事件 / 有效事件"的形式表达,便于后续计算 SLO。
第二步:设定 SLO 并算错误预算
SLO 是 SLI 的目标值,例如"过去 30 天,可用性 SLI ≥ 99.9%"。目标定得越高,代价越大,SRE 强调没有 100% 的 SLO——把目标定在 99.9% 意味着承诺约 43 分钟/月的停机容错,这部分"允许失败"的量就是错误预算。
错误预算 = 100% - SLO,比如 99.9% 对应每月约 43 分钟的"预算"。它最大的价值是给研发节奏提供依据:预算充足时,团队可以放心发布新功能;预算耗尽时,停止上线、全力修复可靠性——"可靠性"从此有了一个与业务对话的货币。
第三步:用燃烧率告警代替固定阈值
传统"延迟超 500ms 告警"在低流量时可能误报、高流量时又可能漏报。Google 推荐基于错误预算燃烧率的告警:按"在 30 天预算窗口内,以多快的速度消耗预算"来告警。典型做法是设两档:
- 页面级(Page):错误率持续消耗预算,预计 2 小时内烧完 → 立即通知值班。
- 工单级(Ticket):预计 1 天内烧完 → 上班时间处理。
这样告警天然与"服务是否在消耗可靠性预算"挂钩,而不是与瞬时阈值挂钩,能显著减少误报。
燃烧率到底怎么算
燃烧率 = 实际错误率 ÷ SLO 允许的错误率。例如 SLO 是 99.9%(允许 0.1% 错误),若当前 5 分钟错误率是 1%,燃烧率就是 10——意味着按这个速度,30 天的预算会在 3 天内烧完(30 ÷ 10)。Google 建议用"多窗口 + 多档燃烧率"兼顾灵敏度与误报率,下面是一组常用档位:
| 档位 | 燃烧率 | 窗口 | 含义 |
|---|---|---|---|
| 页面级(Page) | ≥ 14.4 | 1h / 5m 双窗口 | 预算约 2 小时内烧完,立即值班 |
| 页面级(Page) | ≥ 6 | 6h / 30m 双窗口 | 预算约 5 小时内烧完 |
| 工单级(Ticket) | ≥ 3 | 1d / 2h 双窗口 | 预算约 10 天内烧完,上班处理 |
| 工单级(Ticket) | ≥ 1 | 3d / 6h 双窗口 | 接近预算耗尽,周会关注 |
落到 Prometheus 上,可以用 Recording Rule 先算出错误率,再按窗口生成告警,具体写法参考Prometheus 告警规则:
groups:
- name: slo-burn-rate
rules:
- record: job:slo_errors_total:rate5m
expr: sum(rate(http_errors_total{code=~"5.."}[5m])) by (job)
- record: job:slo_requests_total:rate5m
expr: sum(rate(http_requests_total[5m])) by (job)
双窗口的含义是:短窗口保证"烧得快"时立刻告警,长窗口则避免短时抖动误报。比如页面级用 1 小时 + 5 分钟两个窗口同时满足才触发,既不会漏报突发故障,也不会被一次秒级抖动打扰。
落地清单
- 为每个核心用户旅程定义 1-3 个 SLI,别贪多;
- 设定季度 SLO 与错误预算,并把预算同步给产品团队;
- 配置燃烧率告警,配合 Prometheus 告警规则落地;
- 每周看预算消耗,季度复盘并调整目标。
一个真实的决策场景
设想一家电商站,可用性 SLO 99.9%,错误预算 43 分钟/月。双十一前一周,燃烧率告警连续触发,页面级告警显示预算只剩约 4 小时。此时团队面临的真实选择是:照常发版加购功能,还是先停发、排查告警背后的缓存雪崩?按错误预算的规则,答案很明确——预算见底,停止一切非必要上线,把"可靠性"的优先级提到新功能之上。反过来,如果月初预算还剩 90%,那就没有理由拒绝一次低风险的发布。把"要不要上线"的争论,转变成"预算还剩多少"的数字问题,正是 SLO 最大的管理价值。
一套可参考的站点 SLO 示例
以内容型网站为例,一套务实的 SLO 可能是这样:
| SLI | 口径 | SLO | 错误预算(30 天) |
|---|---|---|---|
| 可用性 | 有效请求成功占比 | 99.9% | 约 43 分钟 |
| 页面加载 | P95 首字节时间 | ≤ 800ms | 不适用(性能 SLO) |
| API 成功率 | 关键 API 非 5xx 占比 | 99.5% | 约 3.6 小时 |
注意两点:性能类 SLO 没有"错误预算"概念,但同样可以有"目标达成率";SLO 不是越多越好,建议每个核心旅程只盯 2-3 个,保证每个目标背后都有对应的告警与负责人。
16IDC 观察
SLO 的价值不在"达成 99.99%",而在用同一个指标语言对齐产品与工程。独立站可以从轻量版开始:用 SLO/SLI 模板定基线,用合成监控口径算可用性(合成监控实战),用 RUM 口径算性能(前端 RUM 监控),再把燃烧率告警接到值班体系(On-call 实践)。更多内容请查看 监控报警分类。
参考:https://sre.google/workbook/error-budget-policy/、https://sre.google/sre-book/service-level-objectives/、https://prometheus.io/docs/practices/slo/