SRE 生产实践:告警降噪策略与实施

文档版本:1.0
创建日期:2026-04-03
适用对象:有一定运维经验的 SRE 工程师、运维团队负责人


一、概述与背景

1.1 什么是告警噪音

告警噪音(Alert Noise)是指运维团队接收到的无效、重复或低价值告警通知的总和。这些告警要么不需要人工干预,要么信息冗余,严重干扰工程师的注意力和判断力。

1.2 问题背景

在现代微服务架构和大规模分布式系统中,监控系统每天可能产生数千甚至数万条告警。根据 Google SRE 团队的研究数据:

  • 90% 的告警是噪音:真正需要人工干预的告警仅占 10% 左右
  • 告警疲劳:工程师在面对大量告警时会逐渐麻木,导致漏掉真正重要的告警
  • 响应延迟:平均告警确认时间与告警数量呈正相关
  • 人力浪费:一个 10 人 On-Call 团队每天花 2 小时处理噪音告警 = 20 人时/天的浪费

1.3 告警降噪的目标

  • 提高信噪比:让真正需要关注的告警浮出水面
  • 减少告警数量:通过聚合、去重、静默等手段减少无效通知
  • 缩短 MTTA/MTTR:平均确认时间和恢复时间
  • 提升 On-Call 体验:避免半夜被无意义的告警吵醒
  • 建立告警质量度量:可量化、可追踪、可改进

二、核心原理

2.1 告警生命周期

┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│  数据采集   │ -> │  规则评估   │ -> │  告警生成   │ -> │  通知路由   │
│ Collection  │    │ Evaluation  │    │ Generation  │    │ Routing     │
└─────────────┘    └─────────────┘    └─────────────┘    └─────────────┘
                                                                │
                                                                v
┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│  告警分析   │ <- │  告警恢复   │ <- │  告警处理   │ <- │  降噪处理   │
│ Analysis    │    │ Resolution  │    │ Handling    │    │ Dedup/Silence│
└─────────────┘    └─────────────┘    └─────────────┘    └─────────────┘

关键降噪环节

  1. 规则评估阶段:避免过度敏感的告警规则
  2. 告警生成阶段:聚合相同来源的告警
  3. 降噪处理阶段:去重、静默、抑制、分组
  4. 通知路由阶段:分级路由、延迟发送

2.2 告警降噪的核心策略

2.2.1 告警分级(Alert Priority)

根据业务影响和紧急程度将告警分为多个级别:

级别 名称 响应时间 通知方式 示例
P0 紧急 5分钟 电话 + 短信 + IM 核心服务不可用
P1 15分钟 短信 + IM 部分功能异常
P2 1小时 IM + 邮件 性能下降
P3 24小时 邮件 资源预警
P4 信息 无需响应 仅仪表盘 自动恢复的瞬时异常

2.2.2 告警去重(Alert Deduplication)

原理:将相同或相似告警合并为一条,避免重复通知。

# Prometheus AlertManager 去重配置示例
route:
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 30s        # 等待 30s 收集同组告警
  group_interval: 5m     # 同组新告警发送间隔
  repeat_interval: 4h    # 未恢复告警重复通知间隔

去重维度选择

  • alertname:告警名称(必须)
  • cluster/namespace:故障域
  • service/job:服务维度
  • severity:严重级别

2.2.3 告警抑制(Alert Inhibition)

原理:当某个告警触发时,自动抑制相关联的低级别或下游告警。

# AlertManager 抑制规则示例
inhibit_rules:
  # 当集群不可用时,抑制该集群下所有服务的告警
  - source_match:
      alertname: 'ClusterDown'
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['cluster']

  # 当基础设施告警触发时,抑制应用层告警
  - source_match:
      alertname: 'NodeDown'
    target_match_re:
      alertname: 'Service.*'
    equal: ['instance']

2.2.4 告警静默(Alert Silencing)

原理:在计划维护或已知问题期间,临时屏蔽特定告警。

# 通过 amtool 创建静默规则
amtool silence add \
  alertname=DeploymentHighCPU \
  cluster=prod-east \
  duration=2h \
  comment="计划内扩容操作"

静默最佳实践

  • 必须添加 comment 说明原因
  • 设置合理的 duration,避免忘记取消
  • 使用 created_by 字段记录创建人
  • 定期审计静默规则,清理过期的

2.2.5 告警聚合(Alert Aggregation)

原理:将多个相关告警合并成一个通知。

原始告警(10条):
  - node-01 CPU > 90%
  - node-02 CPU > 90%
  - node-03 CPU > 90%
  - ...

聚合后(1条):
  【集群告警】prod-east 集群 10/50 节点 CPU 使用率超过 90%

2.2.6 延迟发送(Notification Delay)

原理:对于瞬时抖动,延迟几秒发送,观察是否自动恢复。

# AlertManager 延迟配置
route:
  routes:
    - match:
        severity: warning
      group_wait: 60s    # 等待 60s,让瞬时问题可能自恢复
      receiver: 'team-ops'

2.3 告警质量度量指标

建立可量化的告警质量指标:

指标名称 计算公式 目标值 说明
告警信噪比 有效告警数 / 总告警数 > 30% 越高越好
告警可操作性 有动作的告警 / 总告警 > 50% 是否真的需要处理
平均确认时间(MTTA) Σ(确认时间-告警时间) / 告警数 < 5min P0 告警
平均恢复时间(MTTR) Σ(恢复时间-告警时间) / 告警数 < 30min 业务影响时长
告警风暴次数 单位时间告警 > N 的次数 < 1次/周 避免轰炸
静默覆盖率 静默时长 / 维护时长 ~100% 计划内维护应静默

三、主要功能与应用场景

3.1 核心功能

功能模块 描述 支持工具
告警分级 按严重程度和业务影响分类 Prometheus, Zabbix, Datadog
告警去重 合并相同告警,避免重复通知 AlertManager, PagerDuty
告警抑制 上下游告警联动抑制 AlertManager
告警静默 计划维护期间屏蔽告警 AlertManager, Grafana
告警聚合 合并同类告警为一条通知 AlertManager, VictorOps
延迟发送 等待自恢复后再通知 AlertManager
告警路由 按团队/服务分发告警 AlertManager, OpsGenie
告警升级 未响应时自动升级 PagerDuty, OpsGenie
值班轮转 按排班通知值班人员 PagerDuty, OpsGenie
告警分析 统计分析告警质量 Grafana, Custom Dashboard

3.2 应用场景

场景一:微服务架构下的服务依赖告警抑制

架构拓扑:
  [LoadBalancer] -> [API Gateway] -> [Service A] -> [Database]
                                    -> [Service B] -> [Cache]

当 Database 故障时:
  - Database 告警触发(P0)
  - Service A 告警触发(P1)- 应被抑制
  - API Gateway 告警触发(P1)- 应被抑制
  - LoadBalancer 告警触发(P2)- 应被抑制

预期结果:只收到 Database 告警,其他自动抑制

场景二:容器环境的动态告警管理

# Kubernetes 环境下的告警规则
- alert: PodCrashLooping
  expr: rate(kube_pod_container_status_restarts_total[15m]) > 0.1
  for: 10m    # 避免瞬时重启触发告警
  labels:
    severity: warning
  annotations:
    summary: "Pod {{ $labels.namespace }}/{{ $labels.pod }} 频繁重启"
    description: "过去 15 分钟重启 {{ $value }} 次"

场景三:告警风暴应对

问题:某个服务故障引发 1000+ 条告警,轰炸值班人员

解决方案:
1. 按服务分组(group_by: ['service'])
2. 设置聚合窗口(group_wait: 60s)
3. 抑制下游告警(inhibit_rules)
4. 发送摘要通知而非逐条通知

四、部署与安装步骤

4.1 环境准备

本文以 Prometheus + AlertManager 为例,这是业界最主流的开源告警方案。

系统要求

  • 操作系统:Linux (CentOS 7+/Ubuntu 18.04+)
  • 内存:≥ 2GB
  • 磁盘:≥ 20GB(用于告警历史存储)
  • 网络:能访问被监控服务和通知渠道

4.2 安装 Prometheus

# 1. 创建用户
sudo useradd --no-create-home --shell /bin/false prometheus

# 2. 创建目录
sudo mkdir -p /etc/prometheus
sudo mkdir -p /var/lib/prometheus
sudo chown prometheus:prometheus /var/lib/prometheus

# 3. 下载并安装
cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v2.48.0/prometheus-2.48.0.linux-amd64.tar.gz
tar xvf prometheus-2.48.0.linux-amd64.tar.gz
sudo cp prometheus-2.48.0.linux-amd64/prometheus /usr/local/bin/
sudo cp prometheus-2.48.0.linux-amd64/promtool /usr/local/bin/
sudo chown prometheus:prometheus /usr/local/bin/prometheus
sudo chown prometheus:prometheus /usr/local/bin/promtool

# 4. 创建配置文件
cat << 'EOF' | sudo tee /etc/prometheus/prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - localhost:9093

rule_files:
  - /etc/prometheus/alert_rules.yml

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
EOF

sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml

# 5. 创建 systemd 服务
cat << 'EOF' | sudo tee /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
    --config.file /etc/prometheus/prometheus.yml \
    --storage.tsdb.path /var/lib/prometheus/ \
    --web.console.templates=/etc/prometheus/consoles \
    --web.console.libraries=/etc/prometheus/console_libraries

[Install]
WantedBy=multi-user.target
EOF

# 6. 启动服务
sudo systemctl daemon-reload
sudo systemctl start prometheus
sudo systemctl enable prometheus

# 7. 验证
curl http://localhost:9090/-/healthy

4.3 安装 AlertManager

# 1. 创建用户
sudo useradd --no-create-home --shell /bin/false alertmanager

# 2. 创建目录
sudo mkdir -p /etc/alertmanager
sudo mkdir -p /var/lib/alertmanager
sudo chown alertmanager:alertmanager /var/lib/alertmanager

# 3. 下载并安装
cd /tmp
wget https://github.com/prometheus/alertmanager/releases/download/v0.26.0/alertmanager-0.26.0.linux-amd64.tar.gz
tar xvf alertmanager-0.26.0.linux-amd64.tar.gz
sudo cp alertmanager-0.26.0.linux-amd64/alertmanager /usr/local/bin/
sudo cp alertmanager-0.26.0.linux-amd64/amtool /usr/local/bin/
sudo chown alertmanager:alertmanager /usr/local/bin/alertmanager
sudo chown alertmanager:alertmanager /usr/local/bin/amtool

# 4. 创建配置文件
cat << 'EOF' | sudo tee /etc/alertmanager/alertmanager.yml
global:
  resolve_timeout: 5m
  # 邮件配置
  smtp_smarthost: 'smtp.example.com:587'
  smtp_from: 'alertmanager@example.com'
  smtp_auth_username: 'alertmanager@example.com'
  smtp_auth_password: 'your-password'

# 告警模板
templates:
  - '/etc/alertmanager/templates/*.tmpl'

# 路由配置
route:
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: 'default-receiver'
  routes:
    # P0 告警 - 立即电话通知
    - match:
        severity: critical
      receiver: 'critical-receiver'
      group_wait: 10s
      repeat_interval: 1h
      continue: true

    # P1 告警 - 短信 + IM
    - match:
        severity: warning
      receiver: 'warning-receiver'
      group_wait: 60s
      repeat_interval: 2h

# 接收者配置
receivers:
  - name: 'default-receiver'
    email_configs:
      - to: 'ops-team@example.com'

  - name: 'critical-receiver'
    email_configs:
      - to: 'oncall@example.com'
    # webhook 配置(对接电话/短信网关)
    webhook_configs:
      - url: 'http://webhook-gateway:8080/call'
        send_resolved: true

  - name: 'warning-receiver'
    email_configs:
      - to: 'ops-team@example.com'
    # Slack/钉钉/企微配置
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/XXX/YYY/ZZZ'
        channel: '#alerts'

# 抑制规则
inhibit_rules:
  # 集群故障时抑制节点告警
  - source_match:
      alertname: 'ClusterDown'
    target_match_re:
      alertname: '(NodeDown|ServiceDown)'
    equal: ['cluster']

  # 节点故障时抑制该节点的服务告警
  - source_match:
      alertname: 'NodeDown'
    target_match_re:
      alertname: '.*'
    equal: ['instance']
EOF

sudo chown alertmanager:alertmanager /etc/alertmanager/alertmanager.yml

# 5. 创建 systemd 服务
cat << 'EOF' | sudo tee /etc/systemd/system/alertmanager.service
[Unit]
Description=Prometheus AlertManager
Wants=network-online.target
After=network-online.target

[Service]
User=alertmanager
Group=alertmanager
Type=simple
ExecStart=/usr/local/bin/alertmanager \
    --config.file /etc/alertmanager/alertmanager.yml \
    --storage.path /var/lib/alertmanager

[Install]
WantedBy=multi-user.target
EOF

# 6. 启动服务
sudo systemctl daemon-reload
sudo systemctl start alertmanager
sudo systemctl enable alertmanager

# 7. 验证
curl http://localhost:9093/-/healthy

4.4 创建告警规则

# 创建告警规则文件
cat << 'EOF' | sudo tee /etc/prometheus/alert_rules.yml
groups:
  - name: node_alerts
    rules:
      # 节点宕机告警
      - alert: NodeDown
        expr: up{job="node"} == 0
        for: 5m
        labels:
          severity: critical
          category: infrastructure
        annotations:
          summary: "节点 {{ $labels.instance }} 不可达"
          description: "节点已宕机超过 5 分钟,请立即检查"

      # CPU 使用率过高
      - alert: HighCPUUsage
        expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
        for: 10m
        labels:
          severity: warning
          category: resource
        annotations:
          summary: "节点 {{ $labels.instance }} CPU 使用率过高"
          description: "CPU 使用率 {{ $value | printf \"%.2f\" }}%,持续 10 分钟"

      # 内存使用率过高
      - alert: HighMemoryUsage
        expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
        for: 10m
        labels:
          severity: warning
          category: resource
        annotations:
          summary: "节点 {{ $labels.instance }} 内存使用率过高"
          description: "内存使用率 {{ $value | printf \"%.2f\" }}%"

      # 磁盘空间不足
      - alert: DiskSpaceLow
        expr: (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"}) * 100 < 15
        for: 5m
        labels:
          severity: warning
          category: resource
        annotations:
          summary: "节点 {{ $labels.instance }} 磁盘空间不足"
          description: "磁盘 {{ $labels.mountpoint }} 剩余空间 {{ $value | printf \"%.2f\" }}%"

  - name: service_alerts
    rules:
      # 服务不可用
      - alert: ServiceDown
        expr: up{job="service"} == 0
        for: 3m
        labels:
          severity: critical
          category: application
        annotations:
          summary: "服务 {{ $labels.service }} 不可用"
          description: "服务实例 {{ $labels.instance }} 已宕机超过 3 分钟"

      # HTTP 错误率过高
      - alert: HighErrorRate
        expr: sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100 > 5
        for: 5m
        labels:
          severity: critical
          category: application
        annotations:
          summary: "HTTP 5xx 错误率过高"
          description: "当前 5xx 错误率 {{ $value | printf \"%.2f\" }}%"

      # 响应时间过长
      - alert: HighLatency
        expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 2
        for: 10m
        labels:
          severity: warning
          category: application
        annotations:
          summary: "服务响应时间过长"
          description: "P95 延迟 {{ $value | printf \"%.2f\" }} 秒"

  - name: cluster_alerts
    rules:
      # 集群不可用
      - alert: ClusterDown
        expr: count(up{job="node"} == 1) / count(up{job="node"}) < 0.5
        for: 5m
        labels:
          severity: critical
          category: infrastructure
        annotations:
          summary: "集群 {{ $labels.cluster }} 大规模节点故障"
          description: "超过 50% 节点不可用"

      # 集群容量不足
      - alert: ClusterCapacityLow
        expr: sum(kube_node_status_capacity{resource="cpu"}) - sum(kube_node_status_allocatable{resource="cpu"}) > sum(kube_node_status_capacity{resource="cpu"}) * 0.8
        for: 30m
        labels:
          severity: warning
          category: capacity
        annotations:
          summary: "集群容量不足"
          description: "CPU 资源使用率超过 80%"
EOF

sudo chown prometheus:prometheus /etc/prometheus/alert_rules.yml

# 重载配置
curl -X POST http://localhost:9090/-/reload

4.5 安装 amtool 命令行工具

# amtool 已在安装 AlertManager 时安装,配置自动补全
amtool config

# 设置默认 AlertManager 地址
cat << 'EOF' > ~/.config/amtool/config.yml
alertmanager.url: http://localhost:9093
EOF

# 常用命令
amtool alert query                    # 查询当前告警
amtool silence add alertname=NodeDown # 添加静默
amtool silence query                  # 查询静默规则
amtool check-config /etc/alertmanager/alertmanager.yml  # 检查配置

4.6 安装告警质量监控(可选)

# 创建告警质量监控 Dashboard
cat << 'EOF' | sudo tee /etc/prometheus/alert_quality_rules.yml
groups:
  - name: alert_quality
    rules:
      # 告警总数
      - record: alerts:fired:total
        expr: sum(increase(ALERTS{alertstate="firing"}[24h]))

      # 按严重程度统计
      - record: alerts:fired:by_severity
        expr: sum by(severity) (increase(ALERTS{alertstate="firing"}[24h]))

      # 告警响应时间(需要配合 webhook 记录)
      - record: alerts:ack_latency_seconds
        expr: histogram_quantile(0.95, rate(alert_ack_latency_seconds_bucket[24h]))

      # 静默使用率
      - record: alerts:silence:active_count
        expr: count(ALERTS{alertstate="suppressed"})
EOF

五、常见问题与排查

5.1 安装阶段常见问题

问题 1:Prometheus 无法启动

错误信息:
Error: opening storage: lock DB directory: resource temporarily unavailable

原因:Prometheus 未正常关闭,数据目录锁未释放。

解决方案

# 删除锁文件
rm -f /var/lib/prometheus/lock

# 或使用 promtool 检查数据
promtool tsdb check /var/lib/prometheus/

问题 2:AlertManager 配置语法错误

错误信息:
Error loading config: unknown fields in inhibit_rules: match_re

原因:AlertManager v0.26+ 使用 target_match_re 而非 match_re

解决方案

# 检查配置语法
amtool check-config /etc/alertmanager/alertmanager.yml

# 查看支持的配置项
amtool check-config --help

问题 3:邮件发送失败

错误信息:
notify retry canceled: context deadline exceeded

原因:SMTP 配置错误或网络不通。

排查步骤

# 1. 测试 SMTP 连通性
telnet smtp.example.com 587

# 2. 查看详细日志
alertmanager --log.level=debug --config.file=/etc/alertmanager/alertmanager.yml

# 3. 检查配置
# 确保 smtp_smarthost 格式为 host:port
# 确保 smtp_auth_password 正确(可能需要应用专用密码)

5.2 配置阶段常见问题

问题 4:告警未按预期聚合

现象:配置了 group_by 但仍收到大量告警。

排查步骤

# 1. 检查告警标签
amtool alert query -o extended

# 2. 确认 group_by 字段是否存在
# group_by 中的字段必须在告警标签中存在

# 3. 检查路由配置
amtool config routes

# 4. 测试路由
amtool config routes test alertname=NodeDown severity=critical

常见原因

  • group_by 字段名拼写错误
  • 告警未携带该标签
  • 子路由覆盖了父路由配置

问题 5:抑制规则不生效

现象:上游告警触发后,下游告警仍在发送。

排查步骤

# 1. 检查告警标签是否匹配
amtool alert query -o extended

# 2. 确认 equal 字段值相同
# inhibit_rules 中的 equal 字段必须在 source 和 target 告警中值相同

# 3. 检查抑制状态
amtool alert query --silenced

# 4. 查看 AlertManager UI
# 访问 http://alertmanager:9093,查看 "Silenced" 标签页

常见原因

  • equal 字段值不同(大小写、空格等)
  • source_match 条件过于严格
  • 告警顺序问题(source 告警晚于 target 告警)

问题 6:静默规则误匹配

现象:不该被静默的告警被静默了。

排查步骤

# 1. 查看所有静默规则
amtool silence query

# 2. 测试告警是否会被静默
amtool silence query alertname=NodeDown cluster=prod

# 3. 删除错误的静默
amtool silence expire <silence_id>

最佳实践

  • 使用精确匹配而非正则
  • 添加详细的 comment
  • 设置合理的 duration
  • 定期清理过期静默

5.3 运行阶段常见问题

问题 7:告警风暴

现象:短时间内收到数百条告警。

应急处理

# 1. 立即添加全局静默
amtool silence add duration=1h comment="告警风暴应急处理 - 调查中"

# 2. 查看告警来源
amtool alert query --sort=-starts_at | head -20

# 3. 分析告警模式
amtool alert query -o json | jq '.[] | .labels.alertname' | sort | uniq -c | sort -rn

# 4. 针对性静默
amtool silence add alertname=HighCPUUsage duration=2h comment="已知问题,正在处理"

长期方案

  • 优化告警规则,提高 for 阈值
  • 增加 group_wait 时间
  • 添加更多抑制规则
  • 实现告警摘要通知

问题 8:告警未恢复

现象:问题已解决但告警仍显示 firing。

排查步骤

# 1. 检查指标是否恢复正常
curl 'http://prometheus:9090/api/v1/query?query=ALERTS{alertstate="firing"}'

# 2. 检查 resolve_timeout 配置
# AlertManager 默认 5 分钟未收到告警更新则自动恢复

# 3. 手动解决告警(不推荐)
amtool alert expire <alert_id>

常见原因

  • Prometheus 未发送 resolved 事件
  • resolve_timeout 设置过长
  • 网络问题导致通知丢失

问题 9:延迟发送不生效

现象:配置了 group_wait 但告警立即发送。

原因:AlertManager 的 group_wait 只在首次告警时生效,后续告警使用 group_interval

解决方案

route:
  group_wait: 60s      # 首次告警等待时间
  group_interval: 5m   # 后续告警发送间隔
  repeat_interval: 4h  # 重复通知间隔

# 对于需要更长等待的告警,在子路由中单独配置
routes:
  - match:
      severity: info
    group_wait: 5m     # info 级别等待更长时间

5.4 性能问题排查

问题 10:AlertManager 内存占用过高

排查步骤

# 1. 查看告警数量
amtool alert query | wc -l

# 2. 检查静默规则数量
amtool silence query | wc -l

# 3. 查看 AlertManager 指标
curl http://alertmanager:9093/metrics | grep alertmanager_alerts

# 4. 检查日志
journalctl -u alertmanager -f

优化方案

  • 减少历史数据保留时间(--data.retention
  • 增加聚合力度,减少活跃告警数
  • 定期清理过期静默规则
  • 增加内存限制
# 限制保留时间为 5 天
alertmanager --data.retention=120h

六、生产实践建议

6.1 告警规则设计原则

原则 1:告警必须可操作

❌ 坏的告警:
alert: CPU High
expr: cpu_usage > 80%
问题:没有说明做什么,没有上下文

✅ 好的告警:
alert: WebServerCPUHigh
expr: cpu_usage{service="web"} > 80%
for: 10m
annotations:
  summary: "Web 服务 CPU 使用率持续过高"
  description: "节点 {{ $labels.instance }} CPU 使用率 {{ $value }}%,可能原因:流量激增、代码性能问题、GC 频繁"
  runbook: "https://wiki.example.com/runbooks/cpu-high"

原则 2:告警必须分级

# 不要所有告警都标记为 critical
labels:
  severity: critical  # 仅用于影响业务的事件

labels:
  severity: warning   # 需要关注但不紧急

labels:
  severity: info      # 仅记录,不需要人工干预

原则 3:避免过度敏感

# 坏的配置:瞬时抖动就告警
- alert: ServiceDown
  expr: up == 0
  for: 0m

# 好的配置:等待确认
- alert: ServiceDown
  expr: up == 0
  for: 3m

原则 4:使用多条件告警

# 单条件:内存高就告警(可能是误报)
- alert: HighMemory
  expr: memory_usage > 90%

# 多条件:内存高 + 使用量超过阈值
- alert: HighMemory
  expr: memory_usage > 90% and memory_used_bytes > 10GB
  for: 10m

6.2 告警降噪成熟度模型

等级 特征 降噪措施 告警信噪比
L0 - 原始 告警轰炸 < 5%
L1 - 分级 有优先级 告警分级 5-15%
L2 - 聚合 减少重复 去重 + 分组 15-30%
L3 - 智能抑制 自动降噪 抑制 + 静默 30-50%
L4 - 自愈 自动修复 自动化修复 + 静默 50-70%
L5 - 预测 提前预警 预测性告警 > 70%

6.3 团队协作建议

6.3.1 建立 Runbook

每个告警都应该有对应的 Runbook(操作手册):

# Runbook: NodeDown

## 症状
- Prometheus 无法抓取节点指标
- 节点不可达

## 影响
- 该节点上的服务不可用
- 可能影响集群容量

## 排查步骤
1. 检查网络连通性:`ping <node_ip>`
2. 检查 SSH 连接:`ssh <node_ip>`
3. 检查 IPMI/iDRAC:是否硬件故障
4. 检查云平台控制台:是否被停机

## 解决方案
- 网络问题:检查交换机/防火墙
- 硬件故障:联系机房/云厂商
- 系统崩溃:重启并查看日志

## 升级路径
- 15分钟未恢复:通知二线
- 30分钟未恢复:通知运维经理

6.3.2 定期告警复盘

# 每周统计告警数据
amtool alert query --output=extended > alerts_weekly_$(date +%Y%m%d).json

# 分析维度:
# 1. 告警数量趋势
# 2. Top 10 高频告警
# 3. 告警响应时间
# 4. 误报率(无需处理的告警)
# 5. 漏报率(出问题但无告警)

6.3.3 On-Call 轮值与告警对接

# 对接 PagerDuty / OpsGenie
receivers:
  - name: 'oncall-team'
    pagerduty_configs:
      - service_key: '<pagerduty_service_key>'
        severity: '{{ .Labels.severity }}'
        description: '{{ .Annotations.summary }}'
        details:
          firing: '{{ template "pagerduty.default.instances" .Alerts.Firing }}'
          resolved: '{{ template "pagerduty.default.instances" .Alerts.Resolved }}'
          runbook: '{{ .Annotations.runbook }}'

6.4 监控告警系统的监控

不要忘记监控你的监控系统!

# 监控 Prometheus 自身
- alert: PrometheusDown
  expr: up{job="prometheus"} == 0
  for: 5m
  labels:
    severity: critical
  annotations:
    summary: "Prometheus 实例不可用"

# 监控 AlertManager
- alert: AlertManagerDown
  expr: up{job="alertmanager"} == 0
  for: 5m
  labels:
    severity: critical
  annotations:
    summary: "AlertManager 实例不可用"

# 监控告警延迟
- alert: AlertManagerNotificationsFailed
  expr: rate(alertmanager_notifications_failed_total[5m]) > 0
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "告警通知发送失败"

# 监控规则评估延迟
- alert: PrometheusRuleEvaluationSlow
  expr: prometheus_rule_evaluation_duration_seconds{quantile="0.95"} > 1
  for: 10m
  labels:
    severity: warning
  annotations:
    summary: "告警规则评估延迟过高"

6.5 告警降噪自动化

6.5.1 自动静默(基于维护窗口)

#!/bin/bash
# auto_silence.sh - 自动静默脚本

# 与 CMDB/维护系统对接
MAINTENANCE_WINDOW=$(curl -s http://cmdb/api/maintenance | jq -r '.windows[]')

for window in $MAINTENANCE_WINDOW; do
  service=$(echo $window | jq -r '.service')
  start=$(echo $window | jq -r '.start')
  duration=$(echo $window | jq -r '.duration')

  amtool silence add \
    service=$service \
    start=$start \
    duration=$duration \
    comment="计划维护 - 来自 CMDB"
done

6.5.2 告警降噪建议引擎

#!/usr/bin/env python3
"""
告警降噪建议引擎
分析历史告警数据,提供降噪建议
"""

import requests
from collections import Counter

def analyze_alerts():
    # 获取最近 7 天的告警数据
    alerts = requests.get('http://prometheus:9090/api/v1/alerts').json()

    # 统计高频告警
    alert_names = [a['labels']['alertname'] for a in alerts['data']['alerts']]
    top_alerts = Counter(alert_names).most_common(10)

    suggestions = []
    for alert_name, count in top_alerts:
        # 告警超过 100 次/天,建议优化
        if count > 100:
            suggestions.append({
                'alert': alert_name,
                'count': count,
                'suggestion': '考虑提高阈值或增加 for 时长'
            })

        # 告警自动恢复率 > 80%,建议静默
        auto_resolve_rate = get_auto_resolve_rate(alert_name)
        if auto_resolve_rate > 0.8:
            suggestions.append({
                'alert': alert_name,
                'auto_resolve_rate': auto_resolve_rate,
                'suggestion': '自动恢复率高,考虑添加延迟发送或静默'
            })

    return suggestions

def get_auto_resolve_rate(alert_name):
    # 计算告警自动恢复率
    # 自动恢复 = 告警触发后 5 分钟内恢复
    pass

if __name__ == '__main__':
    suggestions = analyze_alerts()
    for s in suggestions:
        print(f"告警: {s['alert']}")
        print(f"  数据: {s.get('count', s.get('auto_resolve_rate'))}")
        print(f"  建议: {s['suggestion']}")
        print()

6.6 告警降噪 Checklist

部署告警系统时,按此清单检查:

  • 告警分级:所有告警都有 severity 标签
  • 告警去重:配置了合理的 group_by
  • 告警抑制:关键上下游依赖配置了 inhibit_rules
  • 延迟发送:低优先级告警配置了 group_wait
  • 通知路由:不同团队/服务路由到正确的 receiver
  • 值班对接:与 PagerDuty/OpsGenie 等工具集成
  • Runbook:每个告警都有对应的处理文档
  • 监控监控:监控系统自身有监控
  • 告警度量:建立了信噪比、MTTA、MTTR 等指标
  • 定期复盘:有每周/每月的告警复盘机制

七、参考资料

7.1 官方文档

7.2 经典书籍与文章

7.3 开源工具

工具 用途 链接
Prometheus 监控 + 告警规则引擎 https://prometheus.io/
AlertManager 告警降噪 + 路由 https://prometheus.io/docs/alerting/
PagerDuty On-Call 管理 + 升级 https://www.pagerduty.com/
OpsGenie 告警聚合 + 值班 https://www.atlassian.com/software/opsgenie
Grafana OnCall 开源 On-Call 工具 https://grafana.com/oss/oncall/
Karma AlertManager UI 增强 https://github.com/prymitive/karma

7.4 进阶话题

  • 告警即代码:使用 GitOps 管理 AlertManager 配置
  • SLO 驱动的告警:基于服务等级目标的智能告警
  • 告警机器学习:使用 ML 识别告警模式
  • 混沌工程结合:通过故障注入验证告警有效性

总结

告警降噪是一个持续优化的过程,不是一次性任务。从基础的去重、分组开始,逐步建立抑制规则、静默机制,最终实现智能化的告警管理。

记住核心目标:让 On-Call 工程师在半夜被叫醒时,每一次都是真正需要人工干预的关键问题。

度量、改进、再度量 —— 这是告警降噪的永恒循环。


文档结束

results matching ""

    No results matching ""