SRE-SLI-SLO-ErrorBudget实战手册
SLI / SLO / Error Budget 实战手册
SRE 哲学的发动机。没有 SLI/SLO,就没有 “该不该发版”的量化决策依据。本章从定义到告警,给全套可落地的模板和 PromQL。
一、SLI → SLO → Error Budget 的关系链
graph LR
A[用户旅程] --> B[SLI 指标]
B --> C[SLO 目标]
C --> D[Error Budget]
D --> E{预算充足?}
E -->|Yes| F[正常发布]
E -->|No| G[冻结发布<br/>全力修复]
D --> H[烧钱率告警]
H --> I[On-Call 响应]
- SLI(Service Level Indicator):度量。如 “5 分钟内 99.95% 的请求响应时间 < 300ms”
- SLO(Service Level Objective):目标。如 “99.9% 可用性(月度窗口)”
- Error Budget:1 - SLO,即允许的 “错误配额”。99.9% SLO = 每月 43 分钟不可用
[!important] 为什么 100% 不是一个好目标 用户其实分不清 99.99% 和 100%。追求 100% 意味着 0 容忍变更 = 停止发版 = 创新能力归零。Error Budget 就是 “允许你偶尔犯错”的机制,在可靠性和发版速度间找到平衡。
二、SLI 定义工作坊模板
Step 1:定义用户旅程(Critical User Journey)
不要从系统角度定义,从用户视角定义。
以 care-mate 为例:
| # | 用户旅程 | 关键步骤 | 涉及服务 |
|---|---|---|---|
| 1 | 创建护理订单 | 登录 → 填写 → 提交 → 支付回调 | care-mate-api, user-svc, payment-svc |
| 2 | 查看护理记录 | 登录 → 列表 → 详情 | care-mate-api, record-svc |
| 3 | 评价护理员 | 登录 → 评分 → 提交 | care-mate-api, review-svc |
Step 2:为每个旅程选 SLI 类型
| SLI 类型 | 适用场景 | 示例 PromQL |
|---|---|---|
| 可用性 | 任何请求-响应服务 | sum(rate(http_total{status!~"5.."}[5m])) / sum(rate(http_total[5m])) |
| 延迟 | 对响应时间敏感的服务 | histogram_quantile(0.99, sum(rate(http_duration_bucket[5m])) by (le, endpoint)) |
| 吞吐 | API 限流/容量规划 | sum(rate(http_requests_total[5m])) |
| 数据新鲜度 | 数据管道/缓存 | time() - max(cache_last_refresh_timestamp) |
| 持久性 | 存储系统 | sum(rate(storage_write_success_total[5m])) / sum(rate(storage_write_total[5m])) |
Step 3:SLI 规格说明书(实际落地模板)
# sli-spec/care-mate-api.yml
service: care-mate-api
slis:
- name: availability
description: "API 可用性——非 5xx 响应占比"
promql: |
sum(rate(http_requests_total{status!~"5.."}[5m]))
/ sum(rate(http_requests_total[5m]))
unit: ratio
slo_target: 0.999 # 99.9%
- name: latency_p99
description: "创建订单接口 P99 延迟"
promql: |
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket{endpoint="/api/orders"}[5m]))
by (le))
unit: seconds
slo_target: 0.3 # < 300ms
- name: latency_p95
description: "订单列表 P95 延迟"
promql: |
histogram_quantile(0.95,
sum(rate(http_request_duration_seconds_bucket{endpoint="/api/orders/list"}[5m]))
by (le))
unit: seconds
slo_target: 0.5 # < 500ms
slo_window: 30d # 月度窗口
三、选择合适的 SLO 目标
3.1 SLO 定级速查表
| 用户期望 | 可用性 SLO | 月 Error Budget | 周 Error Budget | 适用场景 |
|---|---|---|---|---|
| 极高 | 99.99% | 4.3 min | 1.0 min | 支付、认证 |
| 高 | 99.95% | 21.6 min | 5.0 min | 核心业务 API |
| 中 | 99.9% | 43.2 min | 10.1 min | 一般业务接口 |
| 低 | 99.5% | 3.6 h | 50.4 min | 内部管理后台 |
[!tip] 如何定 SLO——问三个问题
- 用户能忍受多久不可用?(支付 > 管理后台)
- 依赖服务(数据库、Redis)的 SLO 是多少?(你不可能比依赖更可靠)
- 历史上你做到了吗?(先看三个月的数据,SLO 别订得比实际表现还高)
3.2 依赖链 SLO 计算
你的服务 (SLO=99.9%)
├── DB (SLO=99.95%)
├── Redis (SLO=99.99%)
└── 下游 RPC (SLO=99.9%)
组合可用性 = 99.95% × 99.99% × 99.9% = 99.84%
你的 SLO 必须 ≤ 99.84%,否则不可行
四、Error Budget 烧钱率告警——多窗口法
Google SRE 的核心发明:Error Budget Burn Rate Alert。不是简单设阈值,而是用多窗口检测烧钱速度。
4.1 多窗口配置表
| 严重程度 | 短窗口 | 长窗口 | 烧钱率阈值 | 含义 |
|---|---|---|---|---|
| Critical | 1h | 5m | 14.4x | 1h 内烧掉月预算的 2% |
| Warning | 6h | 30m | 6x | 6h 内烧掉月预算的 5% |
| Low | 3d | 6h | 1x | 3 天内烧掉月预算的 10% |
关键设计:短窗口检测快,长窗口防抖动。两个条件同时满足才告警。
4.2 完整告警规则
# rules/error-budget-alerts.yml
groups:
- name: error_budget_alerts
rules:
# ==== 严重级:1h 窗口 + 5m 窗口均 > 14.4x ====
- alert: ErrorBudgetBurn_Critical
expr: |
(
sum(rate(http_requests_total{status=~"5.."}[1h]))
/ sum(rate(http_requests_total[1h]))
) / (1 - 0.999) > 14.4
and
(
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m]))
) / (1 - 0.999) > 14.4
for: 2m
labels:
severity: critical
team: sre
annotations:
summary: "{{ $labels.job }} Error Budget 严重烧钱"
description: |
1h burn rate: {{ $value | humanize }}
预计剩余 Error Budget: {{ . | query "error_budget_remaining_ratio" }}%
# ==== 警告级:6h 窗口 + 30m 窗口均 > 6x ====
- alert: ErrorBudgetBurn_Warning
expr: |
(
sum(rate(http_requests_total{status=~"5.."}[6h]))
/ sum(rate(http_requests_total[6h]))
) / (1 - 0.999) > 6
and
(
sum(rate(http_requests_total{status=~"5.."}[30m]))
/ sum(rate(http_requests_total[30m]))
) / (1 - 0.999) > 6
for: 15m
labels:
severity: warning
team: sre
annotations:
summary: "{{ $labels.job }} Error Budget 中速烧钱"
# ==== 低级别:3d 窗口检测缓慢消耗 ====
- alert: ErrorBudgetBurn_Low
expr: |
(
sum(rate(http_requests_total{status=~"5.."}[3d]))
/ sum(rate(http_requests_total[3d]))
) / (1 - 0.999) > 1
for: 6h
labels:
severity: info
annotations:
summary: "{{ $labels.job }} Error Budget 缓慢消耗(3d 趋势)"
4.3 Error Budget Dashboard 关键面板 PromQL
# 1. 当前 Error Budget 剩余比例
1 - (
sum(increase(http_requests_total{status=~"5.."}[30d]))
/ sum(increase(http_requests_total[30d]))
) / (1 - 0.999)
# 2. 按天展示 Error Budget 消耗
sum(increase(http_requests_total{status=~"5.."}[1d]))
/ sum(increase(http_requests_total[1d]))
/ (1 - 0.999)
# 3. SLO 达标情况(月度)
avg_over_time(
(sum(rate(http_requests_total{status!~"5.."}[5m])) / sum(rate(http_requests_total[5m])))[30d:]
)
# 4. 预计 Error Budget 耗尽时间(天)
(30 * (1 - 0.999)) # 总预算
/ (
sum(rate(http_requests_total{status=~"5.."}[30d]))
/ sum(rate(http_requests_total[30d]))
* 30 * 24 * 3600 # 天 → 秒
)
五、Error Budget 的使用策略
5.1 “燃尽即冻结”策略
Error Budget > 50% → 正常发布(无限制)
Error Budget 20~50% → 发布需 Tech Lead 审批
Error Budget < 20% → 冻结发布,只允许修复
Error Budget 耗尽 → 全员 Gameday,暂停一切变更直到恢复
5.2 Error Budget Policy(团队公约模板)
## Error Budget Policy — care-mate team
### SLO 定义
- 可用性: 99.9%(月度窗口)
- P99 延迟: < 300ms(创建订单接口)
### Error Budget 策略
1. 月度 Error Budget 剩余 > 50%:正常节奏发布
2. 20% ~ 50%:发布需要每周审批一次,附带风险说明
3. < 20%:冻结常规发布,只有 hotfix 和可靠性改进可合入
4. 耗尽:全团队停止功能开发,聚焦可靠性
### 恢复机制
- Error Budget 耗尽后,若连续 7 天 SLO 达标,恢复至 10%
- 每月 1 号重置 Error Budget
### 例外
- 安全漏洞修复不受 Error Budget 限制
- 基础设施变更(如 K8s 升级)使用独立窗口
六、SLO 定义的常见陷阱
[!warning] 坑 1:用平均值代替分位数 P50=50ms 不代表用户体验好——那 1% 的慢请求才是决定性的。永远用 P95/P99。
[!warning] 坑 2:SLO 比依赖系统还高 你依赖的 DB 只有 99.9%,你的 SLO 定 99.99% 纯属骗自己。参见 3.2 节。
[!warning] 坑 3:把所有指标都变成 SLO 建议每个服务 3-5 个 SLO,不会更多。多了没人看,少了不全面。
[!warning] 坑 4:99.9% 和 99.99% 的差别被低估 从 99.9% → 99.99%,可用性提升 10x,但运维成本可能提升 50x。值不值?用 Error Budget 对话来回答。
[!warning] 坑 5:SLO 不 review 每季度 Review SLO 是否合理——业务变了,SLO 也得变。不 review 的 SLO 就是僵尸指标。
七、从 SLI 到自动化的闭环
SLI 定义 → Prometheus Recording Rules
→ Grafana Dashboard(团队全员可见)
→ Alertmanager 告警(Burn Rate)
→ On-Call 响应
→ Postmortem 复盘
→ Action Items(改进可靠性或调 SLO)
→ 回到 SLI 定义
相关笔记
- 可观测性六维信号深度实战 — PromQL 查询模板、告警规则
- SLO SLI 错误预算与智能告警 — 理论篇
- 可观测性知识总览 — 体系总览
- SRE-从零到一实施路线图 — 如何在你的团队落地
- 无指责复盘与故障分析方法论 — Error Budget 耗尽后的复盘流程