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│
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
关键降噪环节:
- 规则评估阶段:避免过度敏感的告警规则
- 告警生成阶段:聚合相同来源的告警
- 降噪处理阶段:去重、静默、抑制、分组
- 通知路由阶段:分级路由、延迟发送
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 经典书籍与文章
- 《Site Reliability Engineering》(Google SRE 书) - Chapter 17: Monitoring Distributed Systems
- 《The Site Reliability Workbook》 - Chapter 9: Incident Response
- Google SRE: Alerting on SLOs
- PagerDuty: Alerting Best Practices
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 工程师在半夜被叫醒时,每一次都是真正需要人工干预的关键问题。
度量、改进、再度量 —— 这是告警降噪的永恒循环。
文档结束