4. SLO 违约检测机制:基于 Prometheus 的告警规则与多窗口多燃烧率算法

SLO 违约检测的核心挑战在于:既要避免因瞬时抖动产生告警风暴,又要在错误预算真正快速消耗时尽早发现。Prometheus 结合多窗口多燃烧率(Multi-Window Multi-Burn-Rate, MWMBR)算法,是目前平台工程中检测 SLO 违约最成熟、最可靠的手段。

4.1 燃烧率与错误预算的关系

燃烧率(Burn Rate)定义为单位时间内消耗错误预算的速度。当燃烧率为 1 时,错误预算恰好在整个 SLO 窗口内均匀消耗完;燃烧率大于 1 意味着预算消耗过快,可能提前违约。

燃烧率 含义 告警严重程度
1.0 错误预算刚好在 SLO 窗口内用完 无告警(正常)
2.0 错误预算在 SLO 窗口一半时间内用完 Warning
5.0 错误预算在 SLO 窗口 20% 时间内用完 Critical
10.0 错误预算在 SLO 窗口 10% 时间内用完 Page(紧急)
关键原则:燃烧率越高,告警响应时间越短。MWMBR 通过组合多个时间窗口和多个燃烧率阈值,实现快速检测与误报抑制的平衡。

4.2 多窗口多燃烧率算法原理

MWMBR 算法同时评估多个时间窗口(如 1 分钟、5 分钟、30 分钟)上的燃烧率,只有当所有窗口的燃烧率都超过对应阈值时,才触发告警。这避免了短时突发流量导致的误报,同时确保持续高燃烧率能被快速捕获。

MWMBR 多窗口多燃烧率检测流程 请求/错误指标流 窗口 1:1min 燃烧率阈值:14.4 窗口 2:5min 燃烧率阈值:6.0 窗口 3:30min 燃烧率阈值:1.0 燃烧率 > 14.4 ? 燃烧率 > 6.0 ? 燃烧率 > 1.0 ? AND 逻辑与 触发告警:SLO 违约风险 所有窗口同时超阈值才告警

4.3 Prometheus 告警规则实现

以下是一组基于 MWMBR 的 Prometheus 告警规则,适用于 30 天 SLO(99.9% 可用性)的检测场景:

groups:
  - name: slo_burn_rate
    interval: 30s
    rules:
      # 1分钟窗口,燃烧率 > 14.4(对应 99.9% SLO)
      - alert: SLOBurnRateVeryHigh
        expr: |
          (
            sum(rate(http_requests_total{status=~"5.."}[1m]))
            /
            sum(rate(http_requests_total[1m]))
          ) * 1440 > 14.4
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "SLO 燃烧率极高(1m 窗口)"
          description: "当前燃烧率 {{ $value }},错误预算将在 2 小时内耗尽。"

      # 5分钟窗口,燃烧率 > 6.0
      - alert: SLOBurnRateHigh
        expr: |
          (
            sum(rate(http_requests_total{status=~"5.."}[5m]))
            /
            sum(rate(http_requests_total[5m]))
          ) * 288 > 6.0
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "SLO 燃烧率较高(5m 窗口)"
          description: "当前燃烧率 {{ $value }},错误预算将在 8 小时内耗尽。"

      # 30分钟窗口,燃烧率 > 1.0
      - alert: SLOBurnRateNormal
        expr: |
          (
            sum(rate(http_requests_total{status=~"5.."}[30m]))
            /
            sum(rate(http_requests_total[30m]))
          ) * 48 > 1.0
        for: 10m
        labels:
          severity: info
        annotations:
          summary: "SLO 燃烧率超过基线(30m 窗口)"
          description: "当前燃烧率 {{ $value }},错误预算将在 24 小时内耗尽。"
公式解析:燃烧率 = (错误率 × 窗口分钟数) / (1 - SLO)。以 99.9% SLO 为例,1 - 0.999 = 0.001,1 分钟窗口的燃烧率阈值 = (0.01 × 1) / 0.001 = 10,实际取 14.4 以留有余量。

4.4 多窗口组合的告警策略

MWMBR 的核心在于组合判断。单一窗口的告警可能被误触发,但多个窗口同时超阈值则表明问题持续存在。下表展示了不同场景下的窗口行为:

场景 1m 窗口 5m 窗口 30m 窗口 是否告警 说明
瞬时流量尖峰 超阈值 未超 未超 否 短时突发,预算消耗可恢复
持续低错误率 未超 未超 未超 否 正常状态
中等错误持续 10 分钟 超阈值 超阈值 未超 否 需继续观察 30m 窗口
严重错误持续 30 分钟 超阈值 超阈值 超阈值 是 错误预算快速消耗,立即响应
缓慢错误增长 未超 超阈值 超阈值 是 长期趋势异常,需关注

4.5 告警疲劳度与抑制机制

为避免告警疲劳,MWMBR 还需要配合以下抑制策略:

  • 告警去重:同一 SLO 在同一时间窗口内只触发一次告警,避免重复通知。
  • 告警升级:从 info → warning → critical 逐级升级,给运维人员缓冲时间。
  • 静默期:告警触发后,同一规则在 30 分钟内不再重复告警,除非燃烧率继续恶化。
  • 依赖抑制:如果底层基础设施(如数据库)已触发告警,上层服务 SLO 告警自动抑制。
告警升级与抑制状态机 正常(OK) 30m 窗口超阈值 Info 5m 窗口也超阈值 Warning 1m 窗口也超阈值 Critical(Page) 依赖抑制 燃烧率恢复 & 静默期结束 告警升级路径:OK → Info → Warning → Critical;虚线表示抑制和恢复路径

4.6 多窗口多燃烧率的工程实践要点

常见陷阱:窗口数量并非越多越好。3 个窗口(短、中、长)已能覆盖绝大多数场景。窗口过多会导致告警延迟增加,且规则维护成本上升。
  1. 窗口选择:推荐使用 1m、5m、30m 三个窗口,分别对应秒级、分钟级、小时级检测粒度。
  2. 阈值校准:燃烧率阈值需根据实际 SLO 目标动态计算,并留出 20%-30% 的余量,避免因指标抖动误告警。
  3. 告警路由:不同严重级别的告警应路由到不同渠道:Info → 日志/看板;Warning → 即时通讯;Critical → 电话/短信。
  4. 定期复盘:每月分析告警记录,调整窗口参数和阈值,使告警准确率保持在 95% 以上。
平台工程最佳实践:将 MWMBR 告警规则封装为 Terraform 模块或 Helm Chart,实现跨集群、跨团队的 SLO 告警标准化部署。每次 SLO 变更时,自动重新计算燃烧率阈值并更新告警规则。