3. Error Budget 计算模型:基于 SLO 的预算计算公式、预算消耗速率、预算剩余周期与燃烧率(Burn Rate)概念

Error Budget(错误预算)是 SRE 实践中的核心量化工具,它将不可靠性视为一种可消耗的资源。本章将深入拆解 Error Budget 的计算模型,从基础公式推导到高级监控指标——燃烧率(Burn Rate),帮助你在自愈系统中实现精确的阈值动态调整。

3.1 基于 SLO 的预算计算公式

Error Budget 的定义非常直观:在 SLO 允许的范围内,系统可以“犯错”的总次数或总时间。其核心公式如下:

Error Budget = 1 - SLO(以小数表示)
或
Error Budget = 总请求量 × (1 - SLO)

在实际工程中,我们通常使用一个滚动窗口(例如 30 天)来计算。假设一个服务的月度 SLO 为 99.9%,月度总请求量为 10,000,000 次:

指标 数值 说明
SLO 99.9% 服务等级目标
总请求量(30天) 10,000,000 滚动窗口内的总事件数
允许的错误次数 10,000 10,000,000 × (1 - 0.999)
初始 Error Budget 10,000 次 周期开始时的可用预算
关键理解: Error Budget 不是“剩余可用时间”,而是“剩余可容忍的失败次数”。当预算耗尽时,系统必须进入保守模式(如熔断降级),以保护剩余的用户体验。

3.2 预算消耗速率与预算剩余周期

仅仅知道剩余预算是不够的,我们需要动态追踪其消耗速率,以预测预算何时会耗尽。这引出了两个关键衍生指标:

  • 预算消耗速率(Budget Consumption Rate, BCR):单位时间内消耗的 Error Budget 比例。公式为:BCR = (已消耗预算 / 总预算) / 时间窗口。
  • 预算剩余周期(Time to Budget Exhaustion, TTE):在当前消耗速率下,预算预计还能维持的时间。公式为:TTE = 剩余预算 / 当前消耗速率。

例如,一个 30 天周期的服务,在第 5 天结束时已经消耗了 50% 的预算:

消耗速率 = 50% / 5天 = 10% / 天
剩余预算 = 50%
TTE = 50% / 10% = 5 天

这意味着如果消耗速率保持不变,预算将在第 10 天耗尽,远早于 30 天的周期结束。这触发了自愈系统的预警。

实践建议: 在监控面板上同时展示“当前消耗速率”和“预算剩余周期”。当 TTE 小于 SLO 周期的一半时,应视为高风险信号,触发熔断降级策略的预演。

3.3 燃烧率(Burn Rate)概念

燃烧率(Burn Rate)是 Error Budget 消耗速率的归一化表示,它衡量的是当前错误率相对于 SLO 允许错误率的倍数。这是自愈系统中触发熔断降级最敏感的指标。

Burn Rate = 实际错误率 / 允许错误率
其中:允许错误率 = 1 - SLO

假设 SLO 为 99.9%(允许错误率 0.1%),当前实际错误率为 1%:

Burn Rate = 1% / 0.1% = 10x

这意味着系统正在以 SLO 允许速率的 10 倍消耗预算。不同的 Burn Rate 对应不同的响应策略:

Burn Rate 范围 消耗速率描述 推荐自愈动作
0 ~ 1x 正常消耗,预算充足 无动作,持续监控
1x ~ 2x 轻度超标,需关注 触发告警,人工评估
2x ~ 10x 中度消耗,预算快速下降 启动局部熔断或限流
10x 以上 严重消耗,预算即将耗尽 全局熔断,降级至兜底服务
注意: 不要仅依赖瞬时 Burn Rate。建议使用多窗口 Burn Rate(如 1分钟、5分钟、30分钟)进行综合判断,避免因短暂流量尖峰导致误触发熔断。

3.4 多窗口 Burn Rate 与自愈决策

为了平衡敏感性与稳定性,成熟的 Error Budget 驱动系统会同时监控多个时间窗口的 Burn Rate。下图展示了基于多窗口 Burn Rate 的自愈决策流程:

多窗口 Burn Rate 自愈决策流程 多窗口 Burn Rate 自愈决策流程 实时指标输入 1分钟窗口 Burn Rate 5分钟窗口 Burn Rate 30分钟窗口 Burn Rate 综合决策引擎 加权投票 / 最大窗口优先 正常:持续监控 告警:局部熔断 紧急:全局降级 说明:短窗口(1分钟)用于快速响应突发故障;长窗口(30分钟)用于识别持续退化,避免误触发。 决策引擎采用“最大窗口优先”原则,当长窗口 Burn Rate 超过阈值时,优先执行降级动作。

3.5 燃烧率与熔断阈值的映射关系

在自愈系统中,Burn Rate 直接决定了熔断降级的阈值。我们可以建立一个动态映射表,将 Burn Rate 映射到具体的熔断参数(如错误率阈值、拒绝请求比例):

// 伪代码示例:基于 Burn Rate 动态调整熔断阈值
function adjustCircuitBreakerThreshold(burnRate) {
    if (burnRate > 10) {
        // 紧急模式:拒绝 90% 请求,错误率阈值降至 1%
        return { rejectionRate: 0.9, errorThreshold: 0.01 };
    } else if (burnRate > 5) {
        // 中度模式:拒绝 50% 请求,错误率阈值降至 5%
        return { rejectionRate: 0.5, errorThreshold: 0.05 };
    } else if (burnRate > 2) {
        // 轻度模式:拒绝 20% 请求,错误率阈值降至 10%
        return { rejectionRate: 0.2, errorThreshold: 0.1 };
    } else {
        // 正常模式:不主动拒绝,错误率阈值保持 SLO 水平
        return { rejectionRate: 0.0, errorThreshold: 0.001 };
    }
}
核心原则: Burn Rate 越高,熔断阈值越激进。这种映射关系使得系统能够在 Error Budget 快速消耗时,自动收紧对错误率的容忍度,从而保护剩余预算,避免 SLO 违约。