4. 告警规则基础:告警三要素、告警状态机与告警分级

告警规则是可观测性体系中最核心的“决策单元”。一条告警规则的本质是:当某个指标在持续一段时间内满足特定条件时,系统应产生一个特定严重级别的通知。本章将拆解告警规则的三个基础构件——指标、阈值、持续时间,并深入理解告警状态机的生命周期与分级策略。

4.1 告警三要素:指标、阈值、持续时间

任何告警规则都可以抽象为三个基本要素的组合。缺少任意一个要素,告警都无法被准确定义和触发。

要素 定义 示例(PromQL / OpenTelemetry) 常见问题
指标(Metric) 被观测的量化对象,通常来自时序数据库或 OTLP 数据流 http_requests_total{status="5xx"} 指标粒度太粗或标签缺失,导致误报
阈值(Threshold) 触发告警的数值边界,可以是静态值或动态基线 > 0.05(错误率 5%) 阈值设置过紧导致风暴,过松导致漏报
持续时间(Duration) 指标在阈值之外必须维持的最短时间窗口 for: 5m 持续时间太短易受毛刺干扰,太长延迟告警
关键原则:三要素必须同时定义。仅定义“指标 + 阈值”而不设持续时间,会导致系统因瞬时抖动频繁告警;仅定义“指标 + 持续时间”而无阈值,则无法判断异常边界。

在 OpenTelemetry 生态中,指标通常通过 OTLP MetricExporter 写入 Prometheus 兼容的后端(如 VictoriaMetrics、Thanos),告警规则则在 Alertmanager 或 Cortex Ruler 中配置。三要素的映射关系如下:

# Prometheus 告警规则示例(标准模板)
groups:
  - name: otel_high_error_rate
    rules:
      - alert: HighErrorRate
        expr: |
          sum(rate(http_server_duration_ms_count{
            http_status_code=~"5.."
          }[5m]))
          /
          sum(rate(http_server_duration_ms_count[5m]))
          > 0.05
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "HTTP 5xx 错误率超过 5%"

4.2 告警状态机:Pending → Firing → Resolved

告警并非“触发即通知”,而是遵循一个严格的状态机模型。理解状态转换是避免告警风暴和重复通知的基础。

告警状态机转换图 Pending 等待中 Firing 触发中 Resolved 已解决 持续时间满足 指标恢复正常 指标再次异常 → 重新进入 Pending 说明:Pending 阶段不发送通知;Firing 阶段发送告警;Resolved 阶段发送恢复通知。

状态转换的详细行为如下:

  • Pending(等待中):指标首次超过阈值,但尚未达到 for 持续时间。此时系统不发送任何通知,仅记录告警处于待确认状态。这是过滤“毛刺”的关键阶段。
  • Firing(触发中):指标在 for 持续时间内始终超过阈值。系统立即发送告警通知,并持续发送(根据 repeat_interval 配置)直到状态变更。
  • Resolved(已解决):指标回落到阈值以下,且持续一个评估周期(通常为 1-2 个 scrape_interval)。系统发送恢复通知,告警生命周期结束。
常见陷阱:如果 for 设置为 0,则指标一旦越界立即进入 Firing,完全跳过 Pending 阶段。这适用于对延迟极度敏感的场景(如支付成功率),但会显著增加告警噪声。建议至少设置 1-3 分钟的 Pending 窗口。

4.3 告警分级:严重度与响应策略

并非所有告警都需要立即唤醒值班工程师。告警分级将告警按影响范围和紧急程度划分为不同等级,每个等级对应不同的通知渠道、响应时间和升级策略。

级别 标签值 典型场景 通知方式 响应要求
P0 / Critical severity: critical 核心服务完全不可用、数据丢失、支付失败 电话 + 即时消息 + 邮件 立即响应(≤5 分钟)
P1 / Warning severity: warning 错误率升高、延迟增加、容量接近上限 即时消息 + 邮件 工作时间内快速响应(≤30 分钟)
P2 / Info severity: info 非关键指标波动、日常维护提醒、版本发布跟踪 邮件 / 告警仪表盘 下一个工作日处理

在 OpenTelemetry 告警规则中,分级通过 labels 字段实现。Alertmanager 根据 severity 标签路由到不同的接收器(receiver):

# Alertmanager 路由配置片段
route:
  group_by: ['alertname', 'cluster']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    - receiver: 'pagerduty-critical'
      match:
        severity: critical
      continue: false
    - receiver: 'slack-warning'
      match:
        severity: warning
      continue: false
    - receiver: 'email-info'
      match:
        severity: info
最佳实践:告警分级应与 SLO(服务等级目标)绑定。例如:错误率违反 SLO 的“消耗预算速度”时触发 Critical,接近 SLO 阈值时触发 Warning。避免将“指标轻微抖动”定义为 Critical,否则值班团队会逐渐对告警麻木。
告警分级响应流程 P0 / Critical 电话 + 即时消息 P1 / Warning 即时消息 + 邮件 P2 / Info 立即响应 ≤5 分钟 快速响应 ≤30 分钟(工作时间) 常规处理 升级策略 P0 未响应 → 5 分钟后 升级到值班经理 P1 未响应 → 30 分钟后 升级到团队负责人 P2 无需升级 自动关闭

4.4 三要素与状态机的联动:一个完整案例

假设我们为 OpenTelemetry 采集的 http.server.duration 指标配置一条告警规则,观察三要素与状态机如何协同工作:

  1. 指标定义:p99_latency 超过 2000ms,基于 5 分钟滑动窗口计算。
  2. 阈值:> 2000(单位:毫秒)。
  3. 持续时间:for: 3m。
  4. 分级:severity: warning(P1)。

当 p99 延迟在 14:00 首次超过 2000ms:

  • 14:00 - 14:02:状态为 Pending,不发送通知。如果延迟在 14:01 回落到 1800ms,告警自动消失,无任何通知。
  • 14:03:延迟持续超过 2000ms 已达 3 分钟,状态转为 Firing。Alertmanager 根据 severity: warning 路由到 Slack 频道,发送告警消息。
  • 14:15:工程师介入,延迟降至 1500ms。下一个评估周期(通常 30-60 秒)检测到指标恢复正常,状态转为 Resolved,发送恢复通知。
自动化要点:在标准模板中,三要素和分级信息应作为告警规则的“元数据”字段存储。OpenTelemetry 的 RuleTemplate 资源模型允许将 metric_name、threshold、duration、severity 定义为模板变量,实现“一次定义,多环境复用”。