SRE 工具
不含糊的 SRE 算术:SLI、SLO、SLA 有什么区别,每一个可用性目标换算成真实分钟是多少,以及燃烧率如何把一个 SLO 变成告警阈值。
3 工具
SLI、SLO、SLA 是三个不同的数
SLI 是一次测量:好事件除以有效事件——在到达负载均衡器的全部请求里,300 毫秒内以
非 5xx 状态被应答的那些。SLO 是这个比值在某个窗口上的目标,比如滚动 30 天内
99.9%。SLA 则是把钱挂到一个通常更宽松的目标上的合同。把它们混为一谈,就会出现
凌晨 3 点为一个谁都没答应要守住的数字把人叫起来。
难的地方是 SLI 的定义,不是那个百分比。两个都声称 99.9% 的团队,含义可能完全不同:
429 算不算错误、健康检查是否进分母、测量点在 CDN 边缘还是在服务内部。先把分子和
分母定下来,再去争几个九。
SLO 随后会导出唯一一个真正改变行为的数:错误预算,100% − SLO。在 30 天窗口上
的 99.9%,你可以失败 0.1% 的请求,或者完全宕机 43.2 分钟。它是一种货币——发布和迁移
在花它,新窗口会补充它,而一个月结束时停在 100% 通常意味着你发布得太慢了。
把可用性目标换成真实分钟
几个九反直觉,分钟不会。每多一个九,允许的停机就除以十。
| 可用性 | 每年(365 天) | 每 30 天月 | 每周 | 每天 |
|---|---|---|---|---|
99% | 3 天 15.6 小时 | 7.2 小时 | 1.68 小时 | 14.4 分钟 |
99.5% | 1 天 19.8 小时 | 3.6 小时 | 50.4 分钟 | 7.2 分钟 |
99.9% | 8.76 小时 | 43.2 分钟 | 10.1 分钟 | 1.44 分钟 |
99.95% | 4.38 小时 | 21.6 分钟 | 5.04 分钟 | 43.2 秒 |
99.99% | 52.6 分钟 | 4.32 分钟 | 60.5 秒 | 8.64 秒 |
99.999% | 5.26 分钟 | 25.9 秒 | 6.05 秒 | 0.86 秒 |
到 99.9% 为止,一个人还能在预算之内察觉、诊断并修复。到了 99.99%,每月的额度是 4.32 分钟——那是关于自动故障切换的承诺,不是关于值班的承诺。
燃烧率:从 SLO 到告警阈值
燃烧率是观测到的错误率除以 SLO 允许的错误率。真正有用的恒等式是
已消耗预算 = 燃烧率 × (窗口 ÷ SLO 周期):它把一次短时间的观测变成关于整个月的论断。
| 燃烧率 | 99.9% SLO 下的错误率 | 全新的 30 天预算多久烧完 | 典型响应 |
|---|---|---|---|
1× | 0.1% | 30 天 | 不告警 |
6× | 0.6% | 5 天 | 呼人(6 小时窗口,已烧 5%) |
14.4× | 1.44% | 50 小时 | 呼人(1 小时窗口,已烧 2%) |
100× | 10% | 7.2 小时 | 立刻呼人 |
1000× | 100%,完全宕机 | 43.2 分钟 | 定为事故 |
给每个快速阈值配一个更短的确认窗口(14.4× 配 5 分钟,6× 配 30 分钟),这样事故
结束时告警也会跟着解除。慢速燃烧属于工单,不属于呼人。
哪个工具回答哪个问题
手上是一个百分比、需要它的时间等价值时,找 SLA 正常运行时间计算器:
它把 0 到 100 之间的任意值换算成每年、每 30 天月、每周和每天允许的停机时长,预设从
90% 到 99.999%。这是合同评审用的工具。
当这个数字必须驱动工程决策时,改用 错误预算计算器。给它一个 SLO、一个以天为单位的窗口和预期流量;它会把预算同时表示成百分比、允许停机时长,以及 可以失败的请求数——30 天窗口的 99.9% 下,一百万里面允许 1,000 个,这个数字在部分降级 的场景下仍然成立,而停机时长不成立。
先要定下哪些响应算“坏”。HTTP 状态码参考 是一个码到含义的查询表——
每个码给出名称、分类和一行描述,可按数字或关键词过滤——于是 400(“无法理解该请求”)
和 422(“格式正确但语义无效”)当场就能分清。它标出了 307 和 308 保留方法,但对
301 会对 POST 做什么只字未提:客户端可能把它改写成 GET 并丢掉请求体,这也是为什
么一个永久迁移的 POST 端点需要 308。要看一个线上端点实际返回什么,
HTTP 头信息检查工具 从 api.sitekits.dev 发起请求,报告最终状态、
重定向跳数、响应时间和每一个响应头;正文从不获取,私有地址或 localhost 目标会被它的
SSRF 防护拒绝。需要请求体、认证头或者 POST?REST API 测试器
从你的浏览器直连目标,所以目标的 CORS 策略会生效。更多内容在
HTTP 工具集 里,那边的重定向矩阵把 301、302、303、307 和
308 并排对照。
要延迟方面的证据,就在 HAR 文件查看器 里打开 DevTools 的导出:每个
请求的方法、状态、类型、大小和耗时,4xx/5xx 高亮。附到工单之前先用
HAR 文件清洗器 脱敏——authorization、cookie、x-api-key、
形似令牌的参数和所有正文都会变成 [REDACTED]。
排程、窗口与时钟
cron 是可靠性工作悄悄崩掉的地方。Crontab 表达式编辑器 解析五
字段表达式,并按浏览器本地时区列出接下来八次触发时间。这张表要当两件事来读:所有 cron
共有的字段取值范围,以及这个编辑器实际能解析的那套更窄的语法——整数与 *、列表、范围
和步长的组合,别的都不行。
| 字段 | 范围 | 编辑器接受的形式 | 别处合法、这里被拒 |
|---|---|---|---|
| 分 | 0–59 | *、5,20、0-30、*/15 | — |
| 时 | 0–23 | 同上 | — |
| 日 | 1–31 | 同上 | L、W(Quartz、AWS) |
| 月 | 1–12 | 同上 | JAN–DEC 名称(Vixie、cronie) |
| 周 | 0–6(0 = 周日) | 同上 | 用 7 表示周日以及 SUN–SAT(Vixie、cronie);5#3(Quartz) |
最后那一列里的所有东西都以同一条消息失败——
Invalid cron expression (expected 5 fields)——即使字段确实有五个,所以
0 3 * * 7 看起来像是数错了,其实是用词不对。周日要写成 0。行级宏(@daily、
@reboot)和带秒的六字段方言会以同样方式被拒,反向范围也一样——22-2 要写成
22-23,0-2。有一种形式则是静默地失败——5/15 被读成单个值 5,而 Kubernetes 风格的
解析器会把它展开成 5-59/15,所以请把范围写全。
还有三件表格显示不了的事。在日期组合上,编辑器应用 POSIX 的“任一匹配”规则——当日和周
两个字段都被限定时,0 0 1 * 1 表示每月 1 日以及每个周一——但它是按文本来判断
是否被限定的,把任何以 * 开头的日期字段都算作未限定。步长会从这个判断里溜过去:
日字段里的 */3 被读成未限定,于是 0 0 */3 * 1 变成与关系,只在落在 1、4、7
号等等的周一触发。把那些日子写成 1-31/3,就能把“任一匹配”规则拿回来。步长切分的是
字段而不是时钟——分钟上的 */7 会在 :00 到 :56 运行,然后带着一个 4 分钟的间隙重新
开始。另外,预览用的是你浏览器的时区,而宿主机时钟通常是 UTC。
事故时间线需要同样的严谨:Unix 时间转换器 把小于 1e12 的值读作秒、更 大的读作毫秒,而 时区转换工具 会在你宣布维护窗口之前,把 同一个时刻钉在 12 个 IANA 时区上并带上正确的 DST 偏移。更多值班工具箱内容: 面向 SRE 的工具。
常见错误
合同里的“月”不是计算器里的“月”
计算器用的是固定的 30 天月和 365 天年。按自然月算,一个 99.9% 的 SLO 在 28 天的二月 允许 40.32 分钟,在七月允许 44.64 分钟——同样的措辞,摆动了 10%。
可用性在依赖链上是乘出来的
三个各自 99.9% 的强依赖串联起来,得到 0.999³ = 99.70%:大约每月 2.16 小时停机,不是
43.2 分钟。没有冗余,你能承诺的上限就是关键路径的乘积。
基于时间和基于请求数的预算不能互换
允许停机时长这个数字假设宕机期间错误率是 100%。一次让 5% 请求失败的降级,会以 50×
烧掉 99.9% 的请求预算,而由合成探测驱动的正常运行时间钟表几乎不动。
你的探测间隔就是分辨率的下限
60 秒一次的合成检测看不见一次 20 秒的中断,而每一次漏掉的探测大约记成一分钟——已经是 99.99% 月度预算的 23%。三个九以上,请从请求日志测量,而不是靠轮询。