路线图

03 可靠性目标:SLI / SLO / SLA

星辉 2026-07-02 阅读 6 min 1,124 字 路线图
03 可靠性目标:SLI / SLO / SLA 封面

概述#

SRE 体系最核心的方法论是量化可靠性。没有 SLI/SLO/SLA 这一套度量框架,可靠性就只能靠感觉——"最近好像不太稳定""这个服务应该可用性很高"。本章从 SLI 选型到 SLO 制定到 SLA 落地,完整建立可靠性量化的知识体系。配合可观测性培养教材(M1-M6)的顶层框架和 SLO 实战文章的工程细节。

读完本章,你应能回答:为什么不用平均延迟?SLO 凭什么是 99.9% 不是 100%?SLA 和 SLO 的缓冲带有什么用?SLI 选取的"用户视角"具体怎么落地?

一、三个概念的定义与关系#

SLI(Service Level Indicator,服务等级指标)#

SLI 是服务质量的具体测量值。它是一个数字,比如"过去 5 分钟 P99 延迟是 230ms"、"过去 1 小时成功率是 99.7%"。

SLI 的核心要求:站在用户视角。CPU 使用率、内存占用、Pod 重启次数这些是基础设施指标,不是 SLI。SLI 衡量的是用户实际感受到的东西——请求成功了没有、页面加载快不快。

判断一个指标是不是合格的 SLI,问三个问题:

  1. 这个指标和用户感受到的服务质量直接相关吗?
  2. 这个指标变差时,用户会察觉到吗?
  3. 这个指标改善时,用户会受益吗?

三个都是"是"——合格 SLI;只要有一个"否",就不是 SLI。例如 CPU 使用率:CPU 80% 时用户可能完全无感(合格 SLI 第一条就过不了);Redis 内存使用率 70% 时用户依然秒级响应(同样不是 SLI)。这些是原因型指标,留给排障下钻用,不进 SLO 体系。

SLO(Service Level Objective,服务等级目标)#

SLO 是给 SLI 定的目标值。比如"月度成功率 ≥ 99.9%""P99 延迟 ≤ 500ms"。SLO 是一个承诺,但不是 100% 的承诺——它明确留出了允许失败的空间。

SLO 不是 SRE 自己定的,是 SRE + 业务方共同协商的结果。SRE 提供技术可行性(系统能达到什么水平),业务方提供用户期望(用户能接受什么水平),SLO 落在两者之间——略高于历史水平、略低于系统能力上限。

SLA(Service Level Agreement,服务等级协议)#

SLA 是在 SLO 基础上叠加了法律/商业后果的正式协议。如果实际表现低于 SLA,通常涉及赔偿(退费、积分、违约金等)。

SLA 不是所有服务都有——内部服务通常没有 SLA(没有赔付对象),只有对外服务(云产品、SaaS、对客 API)才需要 SLA。但 SLO 对所有服务都该有。

三者关系#

text
SLI(测量值) → 用来验证 → SLO(目标值) → 违约触发 → SLA(赔付条款)
   ↑                                                            ↑
   |严格递进:SLI 不准 → SLO 失真 → SLA 误赔                  |
   |                                                          |
   └── 测量层 ───────── 决策层 ───────────── 商业层 ──────────┘

一套完整的可靠性体系是这样运作的:

  • 用 SLI 持续测量服务质量
  • 用 SLO 设置目标(比用户期望略高、比系统能力略低)
  • 用 SLA 对外承诺(含违约条款,通常比 SLO 更宽松)
  • 用 Error Budget 管理 SLO 余量,驱动发布和告警决策

关键公式:SLO 不能等于 SLA。SLO 是内部目标(紧),SLA 是对外承诺(松)。比如一个支付服务的 SLO 是 99.95%,但 SLA 承诺 99.9%,中间差了 0.05% 的缓冲——这 0.05% 就是 SRE 团队的操作空间。如果 SLO = SLA,意味着 SLO 一旦破线就要赔付,SRE 没有任何调整余地。

举个反面案例:某 SaaS 公司把 SLO 和 SLA 都设成 99.9%,结果某月发生一次 30 分钟故障直接触发 SLA 违约,赔了 80 万。复盘发现:SLO 应该明显严于 SLA(视业务留半个到一个九的缓冲),给团队预留出"内部能感知问题、主动修复"的时间窗口。

二、SLI 选型:四类核心指标#

1. 延迟(Latency)#

衡量请求从发出到收到响应的时间。不要用平均值,用分位数

分位数含义使用场景
P5050% 的请求比这个值快参考指标,不进 SLO
P9595% 的请求比这个值快通用 API
P9999% 的请求比这个值快核心服务
P99999.9% 的请求比这个值快支付/交易等对尾延迟极度敏感的场景

为什么平均延迟不可用?假设 99% 的请求 10ms 返回,1% 的请求 10s 超时。平均 = (99×10 + 1×10000) / 100 = 110ms——看起来还好。但 P99 = 10000ms——那 1% 的用户在受苦。平均值掩盖长尾

更进一步,一些团队用 P50 + P99 双指标:

  • P50 反映"大多数用户体验"
  • P99 反映"尾部长尾用户体验"

两者都达标才算 SLO 通过。这样能避免"P50 很好但 P99 极差"的隐性退化。

text
PromQL 示例:
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, job))

# 另一种延迟 SLI:超过阈值(>500ms)的慢请求比例 = 1 - 快请求占比
# 注意 le="0.5" 桶算出的是"≤500ms 的快请求占比",取 1 - 才是"慢请求占比"
1 - (
  sum(rate(http_request_duration_seconds_bucket{le="0.5"}[5m]))
  /
  sum(rate(http_request_duration_seconds_count[5m]))
)

为什么用"超过阈值的比例"而不是 P99 值:P99 是个绝对值(如 800ms),但用户体验是相对的——"800ms 算慢"对搜索 API 和支付 API 是不同的。直接衡量"超过 SLA 阈值的请求比例"更贴近用户感受。例如 SLO 是"99% 的请求 < 500ms",等价于"超过 500ms 的请求比例 < 1%"。

2. 错误率(Error Rate)#

text
error_rate = 失败请求数 / 总请求数

定义"失败"需要明确口径:

  • HTTP 5xx:服务端错误,记失败
  • HTTP 4xx:客户端错误,通常不记失败(但需视业务而定——如果 429 限流是服务端容量不足导致,应记失败)
  • 超时:记失败
  • 业务错误码(如"余额不足"):不记失败(这是正常业务结果)
  • 连接被拒、DNS 解析失败:记失败

实际项目中 4xx 处理是最容易踩坑的。某团队把所有 4xx 都算成失败,结果一次客户端 bug 触发大量 400 Bad Request,错误率告警误报了一周。正确做法:

  • 401/403(未授权/禁止):客户端问题,不记失败
  • 404(未找到):可能是客户端 bug 也可能是正常"资源不存在",看业务
  • 429(限流):服务端容量问题,记失败
  • 499(客户端主动断开,多因服务端响应太慢导致客户端放弃):记失败
  • 400(参数错误):客户端问题,不记失败
text
# 错误率 SLI 的 PromQL(只算 5xx)
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))

# 严格版:(5xx + 429 + 超时) / 总请求
# 分子必须加括号——PromQL 中 / 优先级高于 +,不加括号会算成 5xx + (超时/总数),结果错误
(
  sum(rate(http_requests_total{status=~"5..|429"}[5m]))
  +
  sum(rate(http_request_timeout_total[5m]))
)
/
sum(rate(http_requests_total[5m]))

3. 可用性(Availability)#

text
availability = 成功请求数 / 总请求数 = 1 - error_rate

可用性 SLI 和错误率 SLI 经常是等价的,但某些场景需要分开:

  • 服务返回 200 但内容为空(业务层失败)→ 错误率 SLI 看不出来,需要单独的可用性检查
  • 服务超时不返回任何状态码 → 两种 SLI 都需要覆盖

另一种"可用性"的常见定义是基于时间:服务在统计窗口内"在线"的时间比例。这种口径适合基础设施(如数据库、消息队列),不适合请求-响应式服务。Google SRE Book 推荐用"请求级可用性"而非"时间级可用性"——前者更贴近用户感受。

4. 吞吐量(Throughput)#

text
throughput = 请求数 / 时间窗口(如 QPS、RPM)

吞吐量通常不作为 SLO 的 SLI(因为它是容量指标,不是用户体验指标),但它是容量规划和瓶颈分析的关键数据。

某些场景下吞吐量也间接影响用户体验——当 QPS 接近系统上限时,延迟会显著上升。这种场景可以把"吞吐量达到阈值时的延迟表现"作为复合 SLI。

复合 SLI#

复杂场景需要多个指标组合。例如支付服务:

text
支付成功 SLI = (HTTP 200 返回) AND (业务码 = SUCCESS) AND (延迟 < 3s)

复合 SLI 的实现需要应用层埋点配合——把"成功"这个语义在代码里精确写出来。PromQL 表达:

promql
# 三条件都满足才算成功的复合 SLI
sum(rate(payment_requests_total{http_status="200", biz_code="SUCCESS", duration_le="3"}[5m]))
/
sum(rate(payment_requests_total[5m]))

SLI 选取原则#

  1. 用户视角优先:CPU 高 ≠ 用户受影响,不要用系统指标作 SLI
  2. 2-5 个即可:一个服务超过 5 个 SLI 难以管理,聚焦最影响用户的核心维度
  3. 能被精确测量:如果你的监控系统算不出准确的成功率,那这个 SLI 不成立
  4. 与 SLO 窗口对齐:SLI 的测量窗口要支持 SLO 的评估周期(通常 30 天滚动)
  5. 避免高基数:SLI 标签不要带 user_id、order_id 等高基数维度,否则 Prometheus 会 OOM
  6. 每个 SLI 必须有 owner:没有 owner 的 SLI 是孤儿指标,出问题没人修

参考可观测性培养教材 M5:黄金信号 / RED / USE 方法论——SLI 选取的方法论基础。M1-M6 回答了"怎么看系统",本章回答"怎么用量化指标驱动决策"。

SLI 选取的常见误区#

  • 用基础设施指标代替用户体验指标:CPU 使用率高不一定导致用户受影响,不适合作为 SLI
  • SLI 太多:一个服务超过 5 个 SLI 就难以管理,聚焦在最影响用户的 2-3 个
  • 忽略长尾用户:平均延迟良好不代表没有用户在受苦
  • 只看成功率不看延迟:成功但慢得无法接受也是失败
  • SLI 没有上下文:99% 成功率对内部工具够用,对支付 API 是灾难——SLI 必须和服务等级匹配

三、SLO 制定:为什么不能是 100%#

"99.9% 够不够?"#

99.9%(三个九)的月度 SLO,意味着每月允许约 43 分钟的不可用时间:

text
允许不可用 = (1 - 0.999) × 30天 × 24h × 60min
           = 0.001 × 43200 min
           = 43.2 分钟/月
SLO每年停机时间每月停机时间适用场景
99%3.65 天7.2 小时内部工具
99.5%1.83 天3.6 小时一般业务服务
99.9%8.76 小时43.2 分钟核心业务服务
99.95%4.38 小时21.6 分钟核心交易
99.99%52.6 分钟4.32 分钟支付/对账
99.999%5.26 分钟26.3 秒电信级基础设施

注意这张表里的"停机时间"是按 100% 不可用算的——实际故障通常是"部分用户受影响"或"延迟升高但没完全挂",所以同样的 SLO 在实际场景下能容忍的"故障时长"比表里更长。例如 99.9% 月度预算 43 分钟,如果一次故障只影响 10% 用户,那这次故障可以持续 430 分钟才耗尽预算。

为什么不能设 100%#

1. 成本指数级增长。从 99.9% 到 99.99%,每增加一个九,成本通常翻 3-5 倍——需要多活架构、更严格的发布流程、更冗余的硬件、更多的 on-call。

从→到工程投入典型新增成本
99% → 99.9%监控告警 + 自动恢复+1 名 SRE
99.9% → 99.99%多活 + 灰度发布 + 全链路压测+3-5 名 SRE + 30% 硬件
99.99% → 99.999%异地多活 + 自动切流 + 7×24 NOC翻倍人力 + 翻倍硬件

2. 边际收益递减。用户感知不出来 99.99% 和 99.999% 的区别(后者每年只多 47 分钟可用),但付出的工程成本是天壤之别。

3. 阻碍创新。追求 100% 意味着任何变更都有风险,最终不敢发布,系统变成化石。Google 内部有个观察:SLO 设得过高的团队,反而比 SLO 适中的团队出更多事故——因为发布慢导致每次发布改动大,回归测试覆盖不住。

4. 100% 客观上不存在。即使是 Google、AWS 也不做 100%——因为依赖链上任何一个环节(DNS、网络、硬件)都可能出问题,而这些问题不在你控制范围内。

5. 错误预算是创新的空间。允许失败意味着允许尝试——新功能上线、架构重构、技术债清理都需要消耗一定的错误预算。没有错误预算等于没有试错空间。

SLO 制定的正确思路#

  1. 先问用户期望。你的用户能接受多大程度的不可用?内部知识库和支付接口的答案完全不同。
  2. 再看历史数据。过去 3 个月实际达到的水平是多少?SLO 应该略高于历史水平(有挑战性),但不能脱离现实。
  3. 计算成本。每提高一个九需要投入多少工程资源?这个投入有没有更好的去处?
  4. 用数字说话。"每月允许 43 分钟不可用"比"99.9%"更好沟通——业务方容易理解具体时间。
  5. 分服务等级。不同服务设不同 SLO。核心交易链路 99.99%,辅助功能 99.9%,内部工具 99%——一刀切是错误的。
  6. 留缓冲带。SLO 不能等于历史最佳水平,要留 10-20% 缓冲应对突发流量和意外故障。

SLO 推进路线(从 SLO 实战文章提取)#

text
第一阶段(1-2 个月):只观察,不告警
  → 建 Dashboard,让团队熟悉指标
  → 修正 SLI 计算逻辑(数据对不对)
  → 找出数据异常点,理解为什么
  → 让业务方先看到数字,建立共识

第二阶段(3-4 个月):引入告警,轻量级
  → 只配 P1 告警(快速消耗)
  → 每月做 Error Budget 回顾
  → 建 SLO 违规复盘流程
  → 此时团队对指标有信任,告警才有效

第三阶段(5 个月+):SLO 影响决策
  → Error Budget 冻结策略生效
  → 发布决策参考 Error Budget
  → 每季度回顾并调整 SLO 目标
  → SLO 进 OKR,与团队绩效挂钩

这套推进路线的核心思想是"先建立信任再约束行为"。第一阶段直接上 SLO 告警会触发团队反弹——"我们的指标还没准就告警,是噪音"。先观察 2 个月让团队理解指标含义、修正计算 bug,再上告警,最后才让 SLO 影响发布决策。

来自 A 旗舰可观测性体系的实践经验#

在实际落地中,7 路逐跳测绘发现了几个关键教训:

  • 埋点先行于 SLO。没有合适的埋点(counter/histogram),SLO 是空中楼阁。首批 3 个 SLI(登录成功率、对话完成率、沙箱拉起成功率)在影子运行阶段就暴露了埋点缺口。
  • SLI 计算也需要 Recording Rules。复杂的 PromQL 直接算会导致 Dashboard 和告警都慢。预计算成 job:slo_errors_per_request:ratio_rate5m 这样的 Recording Rule,查询性能提升 10 倍以上。
  • 合成监控兜底真实流量盲区。半夜无用户流量时,真实流量 SLI 没有信号,需要合成监控(cuj-prober)7×24 主动拨测作为兜底。
  • "监控对象多类目体系"纠正"什么都叫 CUJ":第一版调研把 71 个监控点全叫 CUJ(用户旅程),第二版纠正为 CUJ(14 个)+ Invariant(7 个系统不变量)+ SOP(7 个运维动作)+ 横向依赖(6 个)。不同类目用不同的可靠性范式:CUJ 走 SLO + 错误预算,Invariant 走零容忍立刻告警。

SLO 文档模板#

每个 SLO 必须有完整文档,不能只活在 PrometheusRule 里。模板:

markdown
# SLO: 订单服务可用性

## SLI 定义
- 指标名:order_api_availability
- 公式:sum(rate(http_requests_total{job="order-api", status!~"5.."}[5m])) / sum(rate(http_requests_total{job="order-api"}[5m]))
- 测量窗口:5m(实时) / 30d(SLO 评估)

## SLO 目标
- 月度可用性 ≥ 99.9%
- 等价于:每月允许 43 分钟"完全不可用",或更多时长的"部分降级"

## Owner
- 业务 Owner:交易服务部 张三
- SRE Owner:可靠性团队 李四
- 升级路径:SLO 违规 → SRE Owner → 业务 Owner → CTO

## 错误预算政策
- 预算 > 50%:正常发布
- 预算 25%-50%:发布前 review,禁止灰度 > 50%
- 预算 10%-25%:仅修复性发布,新功能冻结
- 预算 < 10%:完全冻结,全员投入修复

## SLA(如有)
- 对外承诺:99.5%(月度)
- 违约赔付:服务信用 10%
- 度量周期:自然月

## 历史数据
- 2026-04:实际 99.92%(达标)
- 2026-05:实际 99.85%(违规,触发复盘)
- 2026-06:实际 99.96%(达标)

四、SLA 与赔付#

SLA 的法律属性#

SLA 不是内部目标,是对外承诺。通常包含:

  • 服务可用性承诺(如 99.9%)
  • 度量方法和统计周期(月度/季度)
  • 未达标的赔付方式(服务信用额度、退款)
  • 免责条款(计划内维护、不可抗力)
  • 客户义务(合理使用、配合排查)
  • 修改条款的通知期(通常 30-90 天)

SLA 设计要点#

  1. SLA 比 SLO 宽松。内部 SLO 99.95%,对外 SLA 99.9%,留缓冲。缓冲大小取决于业务风险偏好——金融类业务缓冲要大(一个九以上),创新业务可以小(半个九)。
  2. 信用额度而非现金赔付。绝大多数云厂商用服务 credit(服务信用),避免直接现金赔付带来的财务和法律复杂性。信用额度通常为月费的 10%-30%,按违约严重度递增。
  3. 明确排除项。计划内维护窗口、客户自身原因、第三方依赖故障、不可抗力等应明确排除。
  4. 连续多月未达标应有升级条款。允许客户无罚金解约。
  5. SLA 度量要有第三方可验证性。客户应该能独立验证 SLA 是否达标,不能只听厂商说。

主流云厂商 SLA 参考#

服务SLA违约赔付
AWS EC299.99% 区域级10%-30% 服务信用
AWS S399.9%10%-25%
AWS RDS99.95%10%-25%
阿里云 ECS99.95%服务信用
Azure VM99.9%10%-25%
GCP Compute Engine99.99% 多实例10%-50%

注意:这些 SLA 通常有"分钟级不可用"才计入的门槛——5 分钟以下的抖动不算。这是云厂商的精算结果,也是 SRE 制定 SLA 时的参考。

五、从可观测性培养教材提取的能力地图#

可观测性培养教材将监控/可观测性能力分为 M1-M6 六层。SRE 可靠性工程在其中的位置:

模块主题SRE 需要掌握什么
M1遥测信号指标/日志/链路三信号的性质和成本特征,SLI 该用哪种信号计算
M2采集管道OpenTelemetry 标准埋点,保证 SLI 数据源可靠
M3存储查询PromQL 写 SLI 表达式和 Error Budget 计算
M4告警与 SRE核心重合区:SLI/SLO/Error Budget、症状告警、燃烧率告警
M5可视化方法论黄金信号/RED/USE 框架指导 SLI 选取
M6架构与治理多集群 SLO 聚合、配置即代码、成本控制

SRE 路线和可观测性培养教材的关系:可观测性教材讲"如何让系统可观测",SRE 路线讲"如何用可观测性做可靠性决策"。两者是上下游关系——可观测性是基础设施,SRE 是上层应用。

实战要点#

  1. SLI 从 2 个开始。第一个服务先选成功率和 P99 延迟两个 SLI,跑顺后再扩展。一开始就上 5 个 SLI 是常见的"过度设计"——团队还没消化就先被指标淹没。
  2. SLO 数字必须经业务方确认。不要 SRE 自己拍——业务方签字的 SLO 才有约束力。最好有邮件或会议纪要留底,将来争议时是依据。
  3. SLA 是法律文件,不要用口头约定替代。让法务或商务团队参与。SLA 一旦签了,修改成本极高(需要通知所有客户)。
  4. Prometheus Recording Rules 先行——参考 DevOps Ch25 部署 Prometheus 后,Recording Rules 是所有 SLO 计算的基础(见 DevOps Ch25 Prometheus 部署)。命名约定:level:metric:operations,如 job:http_requests:success_rate5m
  5. 与 Error Budget 告警联动:SLO 定了之后,下一章讲怎么用 Error Budget 驱动告警和发布决策。
  6. SLO 是动态的,每季度回顾一次。业务变化、用户增长、架构演进都会让原 SLO 不再合适——该调就调,但每次调整都要有数据支撑和文档记录。
  7. SLO 不是越高越好。SLO 设过高的团队反而出更多事故——发布慢导致每次改动大。合适的 SLO 是"比用户期望略高一点",留出 budget 让工程师能折腾新东西。
  8. 多窗口 SLO 告警是 SLO 体系的标配。短窗口(5m/1h)+ 长窗口(6h/30d)AND 条件触发,避免抖动误报和长尾漏报。具体实现见 Ch08 告警工程。

小结#

SLI 是尺子(测量),SLO 是标尺的刻度(目标),SLA 是刻度加后果(违约赔付)。SRE 的核心工作就是用好这把尺子:选对 SLI、定准 SLO、用 Error Budget 守住 SLO。

一个团队是否真正建立了 SLO 体系,看三件事:有没有公开的 SLO Dashboard、有没有月度 SLO 回顾会、有没有因 SLO 违规触发的发布冻结。三件都做到就是真 SLO 体系;只做到其中一两件是"在建立中";一件都没做就是"挂着 SLO 名义的 dashboard 装饰"。

下一章展开 Error Budget——这把尺子怎么变成决策工具,把"可靠性"从口号变成可量化的工程约束。