文章

错误预算与消耗速率告警:在正确的时候呼叫值班

如何把 SLO 转化为告警:真实故障时迅速触发,面对噪声保持安静,问题修复后立即停止。

示例均为通用的说明性内容,并非取自任何客户环境:请根据您自己的系统调整阈值和配置。

从用户的真实体验出发

大多数嘈杂的告警来自对原因——CPU、内存、重启的 Pod——的告警,而不是对用户感受的告警。服务等级指标(SLI)直接度量后者:有效请求中良好请求所占的比例。“良好”可以指没有服务器错误的响应、快于某个阈值的响应,或两者兼有。

服务等级目标(SLO)为这个比例在一个时间窗口内设定目标,例如 30 天内 99.9% 的请求成功。与 100% 之间的差距就是错误预算:这里是 0.1% 的请求,相当于每月约 43 分钟的完全中断。

为什么固定阈值告警会失效

像“错误率连续 5 分钟高于 1%”这样的告警既过于敏感又过于迟钝。它会因一次只消耗了极少预算的短暂尖峰而呼叫值班,却永远不会对悄悄在一周内耗尽全部预算的 0.5% 错误率发出告警。

消耗速率(burn rate)解决了这个问题。它是预算相对于 SLO 被消耗的速度:消耗速率为 1 时,恰好在窗口期内用完预算;消耗速率为 14.4 时,30 天的预算会在两天多一点内耗尽。

多窗口、多消耗速率告警

Google《SRE 工作手册》中描述的方法,将每个消耗速率阈值与一个长窗口和一个短窗口配对:长窗口证明问题足够严重,短窗口证明问题仍在发生。对于 30 天 99.9% 的 SLO,常见的起点是:

  • 呼叫值班:1 小时和 5 分钟内的消耗速率均高于 14.4——一小时内消耗了 2% 的预算。
  • 呼叫值班:6 小时和 30 分钟内的消耗速率均高于 6——消耗了 5% 的预算。
  • 创建工单:3 天和 6 小时内的消耗速率均高于 1——消耗了 10% 的预算。
# Fast-burn page for a 99.9% availability SLO (error budget = 0.001)
(
  sum(rate(http_requests_total{job="api", code=~"5.."}[1h]))
    / sum(rate(http_requests_total{job="api"}[1h]))
) > (14.4 * 0.001)
and
(
  sum(rate(http_requests_total{job="api", code=~"5.."}[5m]))
    / sum(rate(http_requests_total{job="api"}[5m]))
) > (14.4 * 0.001)

短窗口与长窗口同样重要:修复一旦生效,5 分钟内的比例就会下降,告警随之解除,而不是在剩下的一小时里持续触发。

决定成败的细节

  • 记录规则(recording rules):预先计算每个窗口的错误率,让告警表达式保持低开销且易读。
  • 低流量:每分钟只有几个请求时,一次失败就是很高的比例。可以要求最低请求数,或改用合成探测来度量。
  • 延迟类 SLO:把慢于阈值的请求计为不良事件,并使用包含该阈值的直方图分桶。
  • 排除项:事先决定客户端错误和健康检查是否计入,并把规则写在 SLO 旁边。

预算的真正用途

错误预算是决策工具,而不只是呼叫器。预算充足时,团队可以更快发布、承担更有风险的改动;预算耗尽时,可靠性工作优先于新功能,直到趋势恢复。请在第一次违约之前,而不是在违约期间,与产品负责人就这项策略达成一致。

联系

想听听第二种意见?

发送一段对您系统的简短描述。资深工程师会在一个工作日内书面答复。

聊聊您的基础设施