第 13 章 · SLO、错误预算与架构评审
本章建立 可度量的可靠性目标、错误预算治理机制 与 正式架构评审(ARB)流程,把「系统稳不稳」从主观感受变成可计算、可决策的工程语言。
前置:架构 ch07 可观测性;ch09 容量规划与成本估算;ch14 架构工件格式。
后续跟练:ch16 大促评审(预算与 ADR)、ch17 缓存击穿(预算消耗复盘)、ch18 跨机房(RTO/SLO 联动)。
13.1 为什么需要 SLO,而不只是「高可用」
| 常见误区 | 问题 | SLO 视角 |
|---|---|---|
| 「我们要 99.999%」 | 成本指数上升,业务未必需要 | 按用户旅程定目标 |
| 「没宕机就是成功」 | 忽略慢请求、部分失败 | SLI 覆盖成功率 + 延迟 |
| 「出问题再修」 | 无预算概念,变更失控 | 错误预算驱动发布节奏 |
贤紫社区电商(教学案例) 核心用户旅程:
浏览商品 → 加购 → 下单 → 支付 → 物流查询
每条旅程至少定义 1 个 SLI;下单与支付为 Tier-0(直接影响 GMV)。
13.2 SLI / SLO / SLA 三层关系
| 术语 | 定义 | 谁定 | 示例 |
|---|---|---|---|
| SLI | Service Level Indicator,可测量指标 | 工程 | 下单 API 30 天成功率 |
| SLO | Service Level Objective,内部目标 | 工程 + 产品 | 成功率 ≥ 99.9% |
| SLA | Service Level Agreement,对外合同 | 商务/法务 | 未达标赔偿 10% 月费 |
┌─────────────┐
原始遥测 ──► SLI 聚合 ──► 对比 SLO ──► 消耗 Error Budget ──► 发布/冻结决策
└─────────────┘
│
▼
SLA 违约风险(对外)
原则:SLO 应 严于 SLA(留缓冲),例如 SLA 99.9%,内部 SLO 可设 99.95%。
13.3 核心 SLI 选取与 PromQL 实现
13.3.1 好的 SLI 标准
| 标准 | 说明 | 反例 |
|---|---|---|
| 用户导向 | 反映真实体验 | Pod CPU 使用率 |
| 可自动采集 | 无需人工填表 | 「用户满意度」 |
| 稳定定义 | 6 个月内口径不变 | 每周改计算公式 |
| 可行动 | 超标能定位到服务 | 全站笼统可用性 |
13.3.2 贤紫商城 Tier-0 SLI 表
| 服务 | SLI | 测量窗口 | PromQL / 数据源 |
|---|---|---|---|
| order-api | 可用性(非 5xx) | 30d rolling | sum(rate(http_requests_total{service="order-api",status!~"5.."}[5m])) / sum(rate(http_requests_total{service="order-api"}[5m])) |
| order-api | 延迟 P99 | 30d | histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{service="order-api"}[5m])) by (le)) |
| payment-callback | 处理成功率 | 30d | 业务表 callback_status=success / 总数 |
| catalog-api | 搜索 P95 | 7d | Ingress upstream_response_time 或 APM |
| 全站 | 下单完成率 | 大促 24h | 漏斗:orders_created / checkout_started |
小紫云计算 监控告警 中,为每个 SLI 建独立 Grafana 面板,并链到 on-call 路由。
13.3.3 延迟 SLO 的统计陷阱
| 陷阱 | 后果 | 修正 |
|---|---|---|
| 只看平均值 | 掩盖长尾 | 用 P95/P99 |
| 含健康检查 | 拉低延迟 | 过滤 /health |
| 跨地域混合 | 掩盖单机房问题 | 按 cluster 标签拆分 |
13.4 错误预算(Error Budget)深度
13.4.1 可用性预算公式
30 天可用性目标 99.9%
允许不可用比例 = 1 - 0.999 = 0.001
允许不可用时间 = 30 × 24 × 60 × 0.001 = 43.2 分钟/月
| SLO(30 天) | 允许不可用时间 | 允许失败请求(假设 1 亿次/月) |
|---|---|---|
| 99.9% | 43.2 分钟 | 100,000 次 |
| 99.95% | 21.6 分钟 | 50,000 次 |
| 99.99% | 4.32 分钟 | 10,000 次 |
请求数预算(更适合 API 密集型):
错误预算(请求)= 总请求数 × (1 - SLO)
13.4.2 预算消耗与发布策略
| 预算剩余 | 策略 | 工程动作 |
|---|---|---|
| > 50% | 正常迭代 | 功能发布、实验、重构 |
| 20%~50% | 谨慎变更 | 加强灰度、减少数据库 DDL |
| < 20% | 冻结非紧急发布 | 仅 hotfix、安全补丁 |
| 耗尽或 SLA 风险 | 事故响应模式 | 复盘、架构改进、ch17/ch18 类演练 |
Grafana 面板示例文案:
本月错误预算:已消耗 28.5 / 43.2 分钟(66%)
预计月底耗尽:是(按当前燃烧率)
建议:暂停 ch16 类大促外的非核心变更
13.4.3 燃烧率告警(Burn Rate)
Google SRE 实践:不只看累计,还要看 短期燃烧速度。
| 窗口 | 燃烧率倍数 | 含义 | 动作 |
|---|---|---|---|
| 1h | 14.4× | 1 小时烧掉 1 天预算 | 立即 on-call |
| 6h | 6× | 持续恶化 | 升级 P1 |
| 3d | 1× | 匀速消耗 | 周会复盘 |
Prometheus 告警规则示例:
groups:
- name: slo-order-api
rules:
- alert: OrderApiErrorBudgetBurnFast
expr: |
(
1 - (
sum(rate(http_requests_total{service="order-api",status!~"5.."}[1h]))
/
sum(rate(http_requests_total{service="order-api"}[1h]))
)
) > (14.4 * 0.001)
for: 5m
labels:
severity: critical
annotations:
summary: "order-api 1h 错误预算燃烧过快"
13.5 SLO 与容量、成本的三角关系
引用 ch09 容量规划:
容量不足 → P99 超标 → 延迟 SLI 违约 → 错误预算消耗
过度容量 → 成本上升 → 需用 ch09 成本表论证 ROI
| 决策 | 需同时回答 |
|---|---|
| 扩容 3→6 副本 | ch09 公式 + 错误预算是否因延迟燃烧 |
| 降级非核心接口 | ch13 预算 <20% 触发(见 ch16 ADR-016-03) |
| 限流 | 保护 Tier-0,牺牲 Tier-2(推荐商品) |
交叉引用:
- ch09 §9.3 单 Pod 安全 QPS → 支撑 SLO 容量论证
- ch16 大促评审 → 完整 ARB 答辩流程
- ch17 缓存击穿 → 47 分钟事故远超 99.95% 月度预算(21.6 分钟)