CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
可观测性入门/课时/SLO 与错误预算
RawBlame
课时目录12 节

可观测性入门

  1. 01可观测性三支柱
  2. 02指标与 SLI
  3. 03结构化日志
  4. 04分布式链路追踪
  5. 05插桩与埋点
  6. 06监控与告警
  7. 07遥测与 OpenTelemetry
  8. 08Spring 可观测性
  9. 09SLO 与错误预算
  10. 10仪表盘设计
  11. 11故障排查流程
  12. 12综合练习

SLO 与错误预算

衔接 reliability rel-slo。

25 分钟

SLO 与错误预算

这一课你将能做到

  1. 从 SLI 推导一条可执行的 SLO(含时间窗口与目标百分比),并为判题接口写出完整定义
  2. 估算 错误预算,能算出 99.9% 对应每月约 43 分钟的「坏时间」,并说明预算充足/告急时对发布节奏的含义
  3. 用 burn rate(燃烧率) 解释为何需要多窗口告警,能说清「快烧」和「慢烧」的区别和告警策略

为什么要学

指标告诉你「发生了什么」;SLO 告诉团队「怎样才算对用户够好」;错误预算 把稳定与速度变成可谈判的数字。没有 SLO,告警阈值往往拍脑袋——「5xx > 5% 就叫」这种规则既没依据也没共识;有了 SLO,才能决定「预算将尽时冻结功能、专注稳定性」「预算充足时可以大胆灰度发布」。

判题场景典型:比赛期间用户提交量暴涨 10 倍,一次 30 分钟的故障可能烧光整月预算。面试里「SLO 怎么定」「错误预算怎么算」「burn rate 告警怎么设计」是高频题,本课结合 rel-slo 与 obs-metrics;PromQL 实现见 prom-promql。

先建立图像

概念判题系统示例
SLI非 5xx 请求占比;P99 延迟 < 500ms 的请求占比
SLO过去 30 天滚动窗口,可用率 ≥ 99.9%
Error Budget允许的不达标额度:0.1% ≈ 每月约 43 分钟「坏」时间(按时间近似)
Burn Rate当前消耗错误预算的速度 / 「匀速烧完窗口」的速度
预算充足(剩余 > 50%)──► 可加快发布、做实验、灰度更大胆
预算告急(剩余 < 20%)──► 冻结非必要功能、修可靠性、做 postmortem 行动项
预算耗尽(剩余 = 0%)  ──► 只允许稳定性工作(团队协议)

Burn rate 直觉:
  月预算 = 43.2 分钟
  如果 1 小时内烧了 10 分钟(burn rate ≈ 7.2)──► 可能 4~5 小时烧光整月预算 → page
  如果 6 小时烧了 5 分钟(burn rate ≈ 0.7)  ──► 约 9 天烧光 → ticket(工作时间处理)

跟着做

步骤 1:为判题接口写一条完整 SLO

服务:coderoadmap-backend 判题接口
接口:POST /api/judge/submissions
SLI-1 可用率:非 5xx 请求 / 总请求(按 application 标签聚合,滚动 5 分钟窗口)
SLI-2 延迟:P99 < 500ms(http_server_requests_seconds_bucket 直方图)
SLO:任意滚动 30 天窗口,可用率 ≥ 99.9% 且 P99 达标率 ≥ 99%
排除:计划内维护窗口(需提前 24 小时公告并记录)

应得到:可写进 README/运维约定的一句话承诺,而不是「尽量高可用」这种空话。

步骤 2:估算月度错误预算

对 99.9%:允许失败比例 0.1%。

时间口径(适合「系统可用时长」场景):

30 天 × 24 小时 × 60 分钟 × 0.1% = 43.2 分钟
即每月允许约 43 分钟的「不可用时间」

请求口径(适合「按请求数计费」场景):

假设 30 天总请求 1,000,000 次
错误预算 = 1,000,000 × 0.1% = 1,000 次失败

写下你们团队更倾向时间还是请求口径,并保持一致。判题系统推荐请求口径:比赛期间流量集中,时间口径会被低峰期稀释。

步骤 3:把预算接到发布策略

写三条团队规则草案:

1. 预算剩余 > 50%:正常发布流程,可灰度 10% → 50% → 100%
2. 预算剩余 20%~50%:需额外评审,缩小灰度范围,回滚方案必须演练过
3. 预算剩余 < 20% 或已耗尽:只合并稳定性修复和 postmortem 行动项,冻结新功能

对照 rel-postmortem:烧预算的事件必须进复盘,行动项要完成才能「充值」预算。

步骤 4:理解 burn rate 多窗口告警(核心)

单窗口问题:只看「当前错误率 > 1%」无法区分紧急程度——

场景 A:1 小时内错误率 10%,烧了 6 分钟预算
  → burn rate = 6 / (43.2 / 30 / 24) ≈ 10 → 约 4.3 小时烧光整月预算 → 立即 page

场景 B:6 小时错误率 1.5%,烧了 5.4 分钟预算
  → burn rate = 5.4 / (43.2 / 30 / 6) ≈ 1.9 → 约 15 天烧光 → ticket 即可

多窗口告警设计:

# 快烧告警:1 小时窗口,burn rate > 10(可能 4 小时烧光月预算)
- alert: JudgeErrorBudgetBurnFast
  expr: |
    (
      sum(rate(http_server_requests_seconds_count{uri="/api/judge/submissions",status=~"5.."}[1h]))
      /
      sum(rate(http_server_requests_seconds_count{uri="/api/judge/submissions"}[1h]))
    ) > (10 * 0.001)  # 10 倍于匀速烧率
  for: 2m
  labels:
    severity: page

# 慢烧告警:6 小时窗口,burn rate > 2(可能 15 天烧光)
- alert: JudgeErrorBudgetBurnSlow
  expr: |
    (
      sum(rate(http_server_requests_seconds_count{uri="/api/judge/submissions",status=~"5.."}[6h]))
      /
      sum(rate(http_server_requests_seconds_count{uri="/api/judge/submissions"}[6h]))
    ) > (2 * 0.001)
  for: 1h
  labels:
    severity: ticket

应得到:快烧 page、慢烧 ticket,避免「短抖动误 page」和「慢流血无人知」。

步骤 5:核对指标标签与 SLO 一致

SLO 按 application=coderoadmap-backend 聚合;确保 obs-spring 的公共标签存在。多副本在 kubernetes-essentials 中按 Service 汇总,避免只看单 Pod。

步骤 6:算一笔账——今天还能不能发版?

假设:30 天 1,000,000 次请求,SLO 99.9%,错误预算 = 1,000 次
今天已失败 400 次,剩余预算 600 次(60%)

问题:现在能不能发新版?

人话答案:
  预算剩 60% 看起来还行,但要看——
  1. 近期失败集中在哪条路径?如果是判题提交接口,发版风险高
  2. 回滚成本高不高?如果涉及数据库 schema 变更,回滚困难
  3. 是不是比赛窗口?如果是,冻结发布

结论:预算只是输入之一,结合风险评估和发布时间窗口决策

把这笔账写进发布检查清单,SLO 才从海报变成门禁。

讲清楚要点

  1. SLI 是测量、SLO 是目标,所以先有可靠 SLI 再谈 SLO——测不准承诺无意义,见 obs-metrics。
  2. 100% 不可达且昂贵,所以 SLO 故意留错误预算——预算是创新的「燃料」,不是「我们可以烂一点」的借口。
  3. 预算是决策工具,所以要写进发布与 on-call 协议——否则只是墙上海报,没人当回事。
  4. 瞬时错误率不等于预算危机,所以要用 burn rate 看「烧完还剩多久」——单阈值告警无法理解「相对预算的紧急程度」。
  5. 用户路径不同,所以核心 API 与内部批处理应分开 SLO——避免次要路径绑架整体,判题提交和后台统计报表不该共享同一个 SLO。
  6. 告警为行动服务,burn 告警要链到 obs-monitoring 的 runbook——快烧 page 要 30 秒内能看到 Grafana 面板和止血开关。
  7. 依赖下游超 SLO 怎么办?——主路径 SLO 仍对用户负责,但复盘要拆「本服务错误」与「依赖错误」;仪表盘用标签分开,避免把全部火力打到自己的 Deployment。

你可能会懵的地方

  • 99.9% 和 99.99% 差很多吗? 差一个数量级预算:约 43 分钟 vs 约 4.3 分钟/月。目标每加一个 9,成本与工程约束显著上升——多副本、跨区域容灾、变更冻结窗口都要跟上。选 SLO 是商业决策,不是技术攀比。

  • 延迟 SLO 怎么用错误预算? 把「未达延迟目标的请求」当「坏事件」,同样可算预算。例如:P99 < 500ms 达标率 99%,意味着允许 1% 的请求超过 500ms。也可以单独做延迟 SLO,与可用率 SLO 并行。

  • 维护窗口怎么处理? 团队协议:计划内维护是否计入。计入则更严;排除则需严格变更窗口记录(提前公告、限定时段、记录审计)。判题系统比赛期间禁止维护,平时维护窗口要明确排除。

  • 和 rel-slo 重复吗? reliability 课偏组织与策略——怎么定 SLO、怎么写进 SLA、怎么做 postmortem;本课偏如何用可观测信号把 SLO 算出来、告起来——PromQL、burn rate、Grafana 面板。两门课交叉引用,不是重复堆砌。

  • 多窗口 burn 告警为何成对出现? 只看 1 小时会漏「温水煮青蛙」的慢烧——错误率 0.5% 持续一周,每天烧一点,等你发现时预算已耗尽。只看 6 小时又会在短暂毛刺时误叫——发布瞬间的 30 秒错误飙升不该 page。常见配对:短窗快烧(立刻 page)+ 长窗慢烧(工作日处理)。参数要按你们实际流量调,不要抄数字当宗教。

错法对照

错法问题正解
「我们要 100% 可用」不可达且昂贵,团队失去信心选可负担的 SLO(如 99.9%),保留预算
SLO 写了但从不算海报工程,发布决策无依据仪表盘 + burn 告警 + 发布门禁
所有服务共用一个模糊目标次要路径拖垮主路径按用户关键路径拆分 SLO
只看瞬时错误率 page短抖动误报,慢烧漏报结合 burn rate 多窗口告警
次要批任务拖垮主站 SLO内部报表失败影响判题接口承诺分类、权重或独立目标

卡点急救

  1. burn rate 告警公式 PromQL 报错或结果异常:确认分子分母的 [1h] 或 [6h] 窗口一致;确认标签选择器没有拼错(如 uri="/api/judge/submissions" 而非 uri="/api/judge/submissions/");先在 Grafana Explore 里单独跑 expr 验证数值合理。
  2. SLO 面板显示「预算剩余 -50%」:说明已超支。立即启动 postmortem 流程,冻结非必要发布,专注稳定性修复;超支部分不是「欠账下个月还」,而是「这个月已经失败,下个月重新开始」。
  3. 比赛期间流量暴涨,SLO 计算失真:低峰期的成功请求会稀释比赛期间的失败率。解决方案:按请求口径而非时间口径算预算;或为比赛窗口单独定义更严格的 SLO(如 99.95%)。

面试常问

  • SLO 怎么定?错误预算怎么算? 背这个版本:SLO 定义含四要素——SLI(测量指标,如可用率)、目标值(如 99.9%)、时间窗口(如滚动 30 天)、适用范围(如判题提交接口)。错误预算是允许的不达标额度:99.9% 对应 0.1%,时间口径约每月 43 分钟,请求口径按总请求数 × 0.1%。预算的用途:充足时加快发布,告急时冻结功能,耗尽时只做稳定性工作。

  • burn rate 告警为什么需要多窗口? 单窗口无法区分紧急程度。快烧(如 1 小时 burn rate > 10)意味着可能几小时烧光整月预算,必须立即 page;慢烧(如 6 小时 burn rate > 2)意味着十几天才烧光,工作时间 ticket 处理即可。多窗口组合避免「短抖动误 page」和「慢流血无人知」,参数按实际流量调整。

  • SLO 和 SLA 什么区别? SLO 是内部目标,用来指导工程决策(发布节奏、告警阈值);SLA 是外部合同承诺,违约要赔钱。SLO 通常比 SLA 更严格——内部留缓冲,避免外部违约。例如:SLO 99.95%,SLA 99.9%,中间 0.05% 是安全垫。

自测三问

  1. 写出判题接口的一条完整 SLO(含 SLI、目标值、时间窗口、适用范围)。
  2. 99.9% 月度错误预算是多少分钟?如果预算剩 15%,发布策略该怎么调整?
  3. 为什么需要快烧 + 慢烧两种 burn rate 告警窗口?各自的 severity 应该是什么?

小结一句话

SLO 把指标变成产品决策;错误预算让「稳定与速度」可谈判——用烧预算速度决定吵不吵醒人。

延伸

  • Google SRE Workbook:Implementing SLOs
  • Google SRE Book:Alerting on SLOs
  • Prometheus:Recording Rules
  • 下一课《仪表盘设计》:把 SLO、burn rate、RED 指标落成值班能用的 Grafana 看板。
加载本节练习…
← 上一课Spring 可观测性下一课 →仪表盘设计