SLO SLI SLA 区别是什么:用一份公开可用率数据把错误预算算一遍
SLO SLI SLA 区别,一句话说:SLI 是你实际测出来的数(比如“成功请求占比”),SLO 是你给自己定的目标(比如“30 天内成功率不低于 99.9%”),SLA 是写进合同、达不到要承担后果的承诺。三者是“测量、目标、承诺”的关系,SLA 通常比 SLO 宽松,SLO 又建立在一个口径明确的 SLI 上。
下面拿一份公开的逐小时请求计数,把 SLI 的口径、统计窗口和错误预算实际算一遍。同一份 48 小时数据,按请求加权和按小时平均算出来差了将近 9 个百分点。
SLI、SLO、SLA 各自是什么?
| 是什么 | 谁来定 | 例子 | 没达到会怎样 | |
|---|---|---|---|---|
| SLI(服务等级指标) | 一个可测量的比例或数值 | 工程团队 | 成功请求数 / 有效请求数 | 只是一个数,没有后果 |
| SLO(服务等级目标) | SLI 在某个窗口内要达到的目标 | 工程与产品一起定 | 滚动 30 天成功率 ≥ 99.5% | 内部动作:冻结发布、优先修稳定性 |
| SLA(服务等级协议) | 对外的书面承诺 | 商务与法务 | 月可用率低于某值按约定补偿 | 合同后果 |
几个容易混的地方:
- SLI 必须有分子、分母和过滤条件。“可用率 99%”不算 SLI,“过去 30 天,状态码非 5xx 的请求 / 全部请求”才算。
- SLO 一定带窗口。没有窗口的目标没法判断是否达标。
- 不是每个服务都有 SLA。很多服务只公开状态页和历史可用率,没有合同承诺。读状态页的方法可以看怎么看 OpenAI 状态页和 Claude 状态页。
用来演示的数据从哪来?
AGI Plan 在 https://agiplan.dev/api/status/requests?month=YYYY-MM 公开逐小时、逐能力组的成功和失败计数,不需要登录,默认返回 CSV,加 format=json 返回 JSON。AGI Plan 是 cdnping 的商业合作方,这里只把它当作一份口径公开的样本数据,不涉及 AGI Plan 的任何服务条款。cdnping 的 /status/agiplan 页面会镜像展示这份数据。
它的口径写得很清楚:
可用率 = 成功 /(成功 + 因平台自身原因失败),只有 5xx 算平台失败。
也就是说,4xx(包括 401 鉴权失败、429 限流)不进分母。这个选择本身就是 SLI 设计里最常被争论的一点,后面会单独说。
下文所有数字来自 cdnping 在 2026-10-17 18:05(北京时间)对这个接口取的一次快照。cdnping 从 2026-10-17 才开始采集,这只是一个时间点的样本,不是长期统计。
窗口长短会把可用率改变多少?
快照里每个能力组有 1 天、7 天、30 天三个窗口的可用率:
| 能力组 | 1 天 | 7 天 | 30 天 | 30 天请求数 |
|---|---|---|---|---|
| fast(高速轻量) | 77.35% | 81.76% | 81.73% | 44,729 |
| frontier(前沿推理) | 99.76% | 94.22% | 94.41% | 33,729 |
| domestic(国产旗舰) | 98.00% | 98.23% | 98.01% | 9,436 |
| balanced(均衡通用) | 100% | 94.77% | 94.98% | 3,625 |
几点观察:
- 短窗口波动大。balanced 组 1 天是 100%,30 天是 94.98%;如果你只看“今天”,会得出完全不同的判断。frontier 组也是一样,1 天 99.76%,7 天只有 94.22%。
- 窗口太长会稀释近期问题。fast 组 1 天 77.35% 比 30 天低 4 个多百分点,但 30 天的数字看起来“还行”,掩盖了眼下的状况。
- 请求量小的组更敏感。balanced 组 30 天只有 3,625 个请求,几十个失败就能让百分比明显移动。
这就是为什么 SLO 一般用滚动 28 天或 30 天做“是否达标”的判断,同时用 1 小时、6 小时这样的短窗口做告警。两种窗口回答的是不同的问题。
口径不同,同一份数据能差多少?
快照里还有 48 个逐小时桶(北京时间 10 月 15 日 19 时前后到 10 月 17 日 18 时前后),是各组合计的成功和失败数。48 小时合计成功 13,963 次、失败 2,177 次。用三种常见算法算一遍:
| 算法 | 计算方式 | 结果 |
|---|---|---|
| 按请求加权 | 总成功 / 总请求 | 86.51% |
| 按小时平均 | 每小时算一个比例,再取平均 | 95.17% |
| 按“好小时”计 | 成功率 ≥ 99% 的小时数 / 总小时数 | 26 / 48 = 54.2% |
差异主要来自 10 月 16 日 14 时到 16 时这两个小时:共 2,718 个请求,失败 1,599 个,单小时成功率分别是 47.91% 和 34.16%。这两个小时恰好是白天高峰,请求多,所以在“按请求加权”里分量很重;而“按小时平均”把它们和凌晨只有 2 个请求的小时同等对待,结果就被拉高了。
去掉这两个小时,剩下 46 小时按请求加权是 95.69%。另外,前 24 小时是 83.42%,后 24 小时是 94.95%,同一个 48 小时窗口切成两半也会讲出两个故事。
选哪种算法,取决于你想回答什么:
- 按请求加权:反映用户实际碰到失败的概率,大多数 API 服务应该用它。
- 按时间(好分钟/好小时):适合请求量很低、或者更关心“服务能不能用”而不是“多少请求失败”的场景。
- 按小时平均:最好别用,它会让低流量时段替高峰时段“稀释”问题。
4xx 和 429 该不该算失败?
这份数据里没有 4xx 的计数,所以没法算出“把 429 计入失败后可用率是多少”,这里只讲判断方法:
| 状态 | 常见原因 | 建议 |
|---|---|---|
| 5xx | 服务端或上游故障 | 计入失败 |
| 超时、连接重置 | 网络或服务端 | 计入失败,但要区分是不是你自己网络的问题 |
| 429 限流 | 超过配额,或平台过载时主动限流 | 看原因:用户自己超额不计;平台过载触发的应计入 |
| 401/403 | 密钥错误、权限不足 | 一般不计 |
| 400 | 请求格式错误 | 不计 |
关键是把口径写下来,并且在对比两个服务时确认口径一致。一家把 429 算失败、另一家不算,直接比百分比没有意义。自己做探测时的口径问题,自己测 AI API 的可用率里有更细的说明;同一个模型在不同推理供应商上的差异,可以参考同一模型换个 OpenRouter 供应商,可用率能差多少。
几个 9 对应多少停机时间?
按时间口径换算,30 天按 43,200 分钟算:
| 可用率 | 每周 | 每 30 天 | 每年(365 天) |
|---|---|---|---|
| 99% | 100.8 分钟 | 7.2 小时 | 87.6 小时 |
| 99.5% | 50.4 分钟 | 3.6 小时 | 43.8 小时 |
| 99.9% | 10.08 分钟 | 43.2 分钟 | 8.76 小时 |
| 99.95% | 5.04 分钟 | 21.6 分钟 | 4.38 小时 |
| 99.99% | 1.01 分钟 | 4.32 分钟 | 52.6 分钟 |
| 99.999% | 6.05 秒 | 25.9 秒 | 5.26 分钟 |
如果你的 SLI 是按请求算的,就把“分钟”换成“请求数”:允许失败数 = 窗口内总请求 ×(1 − SLO)。
错误预算怎么算?
错误预算就是 SLO 允许你失败的那部分。以 frontier 组为例,30 天 33,729 个请求:
- 假设 SLO 定为 99%,预算是 33,729 × 1% ≈ 337 个失败请求。
- 按 30 天可用率 94.41% 反推,实际失败约 1,887 个,大约是预算的 5.6 倍。
- 假设 SLO 定为 95%,预算约 1,686 个,实际仍略超。
再看 domestic 组:9,436 个请求,30 天可用率 98.01%,反推失败约 188 个。在 98% 的目标下预算约 189 个,刚好贴着线;在 99% 的目标下预算约 94 个,已经用掉两倍。
同一组数据,目标定在哪里,结论就完全不同。所以 SLO 不应该拍脑袋定成“99.9%”,而应该先看过去一段时间的实际 SLI,再决定。
还有一个常用的概念是消耗速率(burn rate):实际失败比例 ÷ 预算比例。SLO 是 99% 时,某小时失败率 10%,消耗速率就是 10,意思是照这个速度,30 天的预算 3 天就会用完。10 月 16 日 14 时那一小时失败率约 52%,相对 99% 的 SLO 消耗速率约 52,一小时就用掉了 30 天预算的 7% 左右。告警通常按消耗速率设,而不是按某个固定百分比。
动手:用公开接口自己算一遍
- 下载当月数据,先看表头和字段:
curl -s 'https://agiplan.dev/api/status/requests?month=2026-10' -o req.csv
head -3 req.csv
- 确认哪一列是时间、能力组、成功数、失败数。下面的命令假设成功数在第 3 列、失败数在第 4 列,并且有一行表头,请按实际表头调整列号:
# 按请求加权的整体可用率
awk -F, 'NR>1 {ok+=$3; f+=$4} END {printf "ok=%d failed=%d sli=%.4f\n", ok, f, ok/(ok+f)}' req.csv
# 成功率 >= 99% 的“好小时”占比(按行计,每行一个小时 × 能力组)
awk -F, 'NR>1 && ($3+$4)>0 {n++; if ($3/($3+$4) >= 0.99) g++} END {printf "good=%d/%d\n", g, n}' req.csv
- 把两个结果对比一下,再试着去掉某个能力组、或者只看工作时间,观察数字怎么变。
自己的服务也可以照这个流程走:先导出逐小时的成功、失败计数,再算。
小团队怎么给 AI 应用定第一版 SLO?
一份可以照着走的检查表:
- 选一个用户能感知的 SLI。AI 应用最常见的是“调用上游模型的请求中,非 5xx 且未超时的比例”。延迟可以另起一个 SLI,例如“首 token 时间低于 N 秒的请求比例”。
- 写清过滤条件。4xx 计不计、429 怎么区分、客户端主动取消算不算,全部写进文档。
- 先测两到四周再定目标。用实际 SLI 的水平作为起点,目标定在略高于现状的位置,而不是先写 99.9% 再发现永远达不到。
- 考虑上游。如果你依赖的模型 API 自己只有某个水平,你的 SLO 很难比它更高,除非做了重试或多供应商切换。上游状态可以在 API 状态 和 挂了吗 查看,故障记录可以参考 AI 服务故障盘点:2026 年 9–10 月。
- 按消耗速率定两档告警,每档配一长一短两个窗口,两个窗口都超阈值才触发,减少误报。Google SRE Workbook 针对 30 天 99.9% 的 SLO 给过一组参考值:1 小时和 5 分钟窗口的消耗速率都超过 14.4 时立即通知;6 小时和 30 分钟窗口都超过 6 时也通知。数值按自己的 SLO 和流量调整。
- 约定预算用完后的动作。例如暂停非紧急上线、优先处理稳定性问题。没有动作的 SLO 只是一个看板数字。
探测脚本、告警配置这些具体实现,可以接着看 AI 应用可用性监控怎么做。cdnping 自己的探测方式和口径写在 数据方法 页面。
读别人的可用率数字时先问哪几个问题?
- 分子分母是什么,4xx、429、超时怎么算?
- 窗口是 1 天、7 天还是 30 天,是自然月还是滚动?
- 按请求加权还是按时间算?
- 是服务端统计的真实请求,还是外部探测?外部探测是固定间隔的抽样(例如 cdnping 的 API 状态每 5 分钟探测一次),和真实请求的结果不能直接比。
- 能不能拿到原始计数自己复算?
评估第三方 API 服务时,这几条可以和AI API 中转站怎么选:8 项检查一起用。