3. 告警规则结构解析:Alerting Rule 的 YAML 结构、expr 表达式、for 持续时间、labels 与 annotations 设计

告警规则是 Prometheus 可观测性体系的“触发开关”。一个结构严谨的 Alerting Rule 不仅决定了告警是否准确,还直接影响后续的自愈剧本能否正确执行。本章将逐层拆解 Alerting Rule 的 YAML 骨架,深入分析 expr、for、labels 和 annotations 四个核心字段的设计原则与调优方法。

3.1 Alerting Rule 的完整 YAML 结构

一个标准的告警规则定义在 Prometheus 的 rules/*.yml 文件中,其顶层结构如下:

groups:
  - name: <group_name>                # 规则组名称,用于逻辑分组
    interval: <evaluation_interval>    # 该组规则的评估周期(可选,默认继承全局配置)
    rules:
      - alert: <alert_name>            # 告警名称,必须唯一
        expr: <promql_expression>      # PromQL 表达式,触发条件
        for: <duration>                # 持续时间,防止抖动
        labels:                         # 附加标签,用于路由与去重
          <key>: <value>
        annotations:                    # 注解,用于告警消息内容
          <key>: <value>
设计要点: 规则组 group_name 建议按业务模块或告警级别命名(如 high_availability、performance_critical),便于后期维护与批量调优。

3.2 expr 表达式:告警触发的核心逻辑

expr 是 PromQL 表达式,它定义了“什么时候该告警”。表达式的结果必须是一个瞬时向量,且向量中的每个样本都代表一个潜在的告警实例。

表达式类型 示例 说明
阈值比较 node_cpu_seconds_total > 0.9 当 CPU 使用率超过 90% 时触发
变化率检测 rate(http_requests_total[5m]) < 100 5 分钟内请求速率低于 100 QPS
缺失数据 absent(up{job="api-server"}) == 1 目标实例完全无数据上报
聚合对比 sum by (instance) (rate(cpu_seconds_total[1m])) > 0.8 按实例聚合后,任一实例 CPU 超过 80%
常见陷阱: 避免在 expr 中使用 offset 或 @ 修饰符进行历史数据回溯,这会导致告警评估结果与当前时间窗口错位,增加自愈剧本的误判风险。

3.3 for 持续时间:消除抖动与误告警

for 字段定义了告警条件必须持续满足多长时间后,告警状态才会从 Pending 转为 Firing。这是防止瞬时峰值或网络抖动引发无效告警的关键参数。

# 示例:CPU 高负载持续 5 分钟才触发告警
- alert: HighCpuUsage
  expr: node_cpu_seconds_total > 0.9
  for: 5m

调优建议:

  • 基础设施类告警(如 CPU、内存):推荐 for: 2m ~ 5m,避免毛刺。
  • 业务类告警(如错误率、延迟):推荐 for: 30s ~ 1m,快速响应。
  • 自愈剧本联动:如果自愈动作需要快速介入,for 不宜过长,建议 ≤ 2m。
自愈场景提示: 当 for 设置为 0 时,告警条件一旦满足立即触发 Firing。这在自愈剧本中可用于“零容忍”类告警(如进程崩溃),但需配合更严格的抖动抑制策略。

3.4 labels 设计:告警路由与去重标识

labels 是告警的元数据标签,用于告警分组、路由(如 Alertmanager 的 route 匹配)和去重。设计良好的 labels 能显著提升告警治理效率。

标签键 推荐值 作用
severity critical / warning / info 告警级别,用于 Alertmanager 路由与通知优先级
team sre / backend / infra 负责团队,用于告警分派
service api-gateway / user-service 服务名称,用于告警聚合与自愈剧本匹配
action restart / scale-up / clean-cache 自愈动作标识,直接驱动自愈剧本选择
# 自愈场景下的 labels 设计示例
- alert: ApiHighErrorRate
  expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
  for: 1m
  labels:
    severity: critical
    team: sre
    service: api-gateway
    action: restart-pod
设计原则: labels 应保持“少而精”。避免将动态变化的值(如当前 CPU 使用率)写入 labels,这会导致告警基数爆炸,影响 Alertmanager 性能。

3.5 annotations 设计:告警消息的内容模板

annotations 用于携带告警的详细描述、当前值、建议操作等人类可读信息。这些内容会直接出现在告警通知(邮件、钉钉、Slack)中,是值班人员的第一手资料。

注解键 推荐模板 说明
summary {{ $labels.instance }} CPU 使用率超过 90% 简短总结,用于标题
description 实例 {{ $labels.instance }} 当前 CPU 使用率为 {{ $value | humanizePercentage }},已持续 {{ $for }},请检查。 详细描述,包含当前值与持续时间
runbook_url https://wiki.xxx.com/runbooks/high-cpu 应急预案链接,加速故障恢复
auto_recovery true / false 自愈剧本是否自动执行,用于控制台展示
# 完整的 annotations 示例
annotations:
  summary: "{{ $labels.instance }} 错误率过高"
  description: "实例 {{ $labels.instance }} 在最近 5 分钟内的 5xx 错误率为 {{ $value | humanizePercentage }},超过阈值 5%。"
  runbook_url: "https://runbook.team/api-error"
  auto_recovery: "true"
注意事项: annotations 中可以使用 {{ $value }}、{{ $labels }} 等模板变量,但不要将大量原始指标数据塞入 description,避免通知消息过长。建议只包含关键指标与上下文。

3.6 结构总览:从 YAML 到告警生命周期的映射

下面的 SVG 图展示了 Alerting Rule 各字段在告警生命周期中的位置与作用:

Alerting Rule 结构映射图 Alerting Rule 结构 → 告警生命周期映射 YAML 规则定义 alert / expr / for PromQL 评估 expr 表达式计算 Pending 状态 for 持续时间等待 Firing 状态 告警触发 路由与通知 labels 匹配 route 自愈剧本执行 annotations 驱动动作 💡 关键映射关系: • expr → PromQL 评估 → 决定是否进入 Pending • for → Pending 持续时间 → 决定是否转为 Firing • labels → 路由匹配 → 决定通知目标与自愈剧本

3.7 字段设计对比速查表

以下表格总结了四个核心字段的设计目标与调优方向,便于在自愈剧本开发时快速参考:

字段 设计目标 调优方向 自愈剧本关联
expr 精确描述触发条件 避免复杂聚合,优先使用 rate/increase 平滑指标 直接决定自愈动作的触发时机
for 消除抖动,确认持续性 基础设施 2-5m,业务 30s-1m,自愈联动 ≤2m 影响自愈剧本的响应延迟
labels 路由、去重、分派 保持标签基数可控,severity/team/action 为必选 action 标签直接映射自愈剧本 ID
annotations 提供上下文与操作指引 使用模板变量,避免过长,包含 runbook_url auto_recovery 注解控制是否自动执行
实战建议: 在自愈剧本开发初期,建议先为每个告警规则定义 action 标签和 auto_recovery 注解。这样可以在不修改 PromQL 逻辑的前提下,通过调整 labels 和 annotations 快速切换自愈策略,实现“告警与自愈的解耦”。