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