在 Prometheus 生态中,Prometheus 负责根据告警规则产生告警,而 Alertmanager 负责告警的后续全生命周期管理:分组、路由、抑制、去重和通知发送。一个配置不当的 Alertmanager 会让值班人员在凌晨被海量重复告警淹没,而精心设计的路由与抑制策略能确保"正确的人、在正确的时间、收到正确的告警"。
一、Alertmanager 架构
Alertmanager 的处理流水线分为五个阶段:
Prometheus 告警规则触发
│
▼
┌───────────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ 接收 Receive │ ──→ │ 分组 Group │ ──→ │ 路由 Route │ ──→ │ 抑制 Inhibit│ ──→ │ 去重 Dedup │
└───────────────┘ └───────────┘ └───────────┘ └───────────┘ └─────┬─────┘
│
▼
┌───────────────┐
│ 发送 Notify │
│ 邮件/微信/钉钉 │
└───────────────┘
| 阶段 | 作用 | 关键配置 |
|---|---|---|
| 接收 | 接收来自 Prometheus 的告警 | receivers |
| 分组 | 将相同特征的告警合并为一批 | group_by |
| 路由 | 根据标签匹配决定告警去向 | route、matchers |
| 抑制 | 当某告警触发时,静默相关低优先级告警 | inhibit_rules |
| 去重 | 多个 Alertmanager 实例间的告警去重 | HA 模式 + Gossip |
| 发送 | 通过配置的渠道发送通知 | webhook / email / 等 |
二、路由树设计
2.1 路由树结构
Alertmanager 的路由是一棵树,根节点是默认路由,每个子节点通过 matchers 匹配标签:
route:
receiver: default
group_by: ['alertname', 'cluster']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
# 严重告警 → 立即通知
- matchers:
- severity="critical"
receiver: critical-pager
group_wait: 0s
repeat_interval: 1h
# 警告级别 → 延迟通知
- matchers:
- severity="warning"
receiver: warning-channel
group_wait: 5m
repeat_interval: 4h
routes:
# 数据库相关警告 → DBA 团队
- matchers:
- team="dba"
receiver: dba-team
continue: false
# 告警恢复通知 → 统一发送
- matchers:
- alertname=~"NodeDown|HostUnavailable"
receiver: infra-team
2.2 matchers 语法
从 Alertmanager v0.22 起,matchers 使用统一语法替代了旧的 match / match_re:
matchers:
# 精确匹配
- severity="critical"
# 正则匹配
- alertname=~"Node.*"
# 不等于
- severity!="info"
# 正则不匹配
- instance!~"localhost.*"
# 检查标签是否存在(值为空)
- "maintenance"
# 检查标签不存在
- "!staging"
2.3 continue 关键字
默认情况下,告警匹配到某个子路由后就不会继续匹配后续同级路由。设置 continue: true 可以让告警同时走多个接收者:
routes:
- matchers:
- severity="critical"
receiver: pagerduty
continue: true # 继续匹配下一个路由
- matchers:
- severity="critical"
receiver: slack-critical
上面的配置让严重告警同时发送到 PagerDuty 和 Slack。
2.4 级联路由示例
routes:
# 第一级:按团队分流
- matchers:
- team="sre"
receiver: sre-default
routes:
# 第二级:SRE 中的严重告警
- matchers:
- severity="critical"
receiver: sre-critical
# 第二级:SRE 中的磁盘告警
- matchers:
- alertname=~"Disk.*"
receiver: sre-storage
- matchers:
- team="dba"
receiver: dba-default
routes:
- matchers:
- severity="critical"
receiver: dba-critical
三、分组策略
分组决定了"哪些告警会被合并成一条通知"。
3.1 核心参数
| 参数 | 说明 | 典型值 |
|---|---|---|
group_by | 按哪些标签分组 | ['alertname', 'cluster', 'service'] |
group_wait | 首次告警后等待多久再发送(等待更多同组告警) | 30s |
group_interval | 同组新告警合并后,下次发送间隔 | 5m |
repeat_interval | 同一告警重复通知间隔 | 4h |
3.2 分组时间线示例
假设 group_by: ['alertname'],group_wait: 30s,group_interval: 5m:
t=0s 收到 AlertA(instance=node-1)
→ 开始等待 30s(group_wait)
t=10s 收到 AlertA(instance=node-2) → 同组,合并
t=30s 发送通知 [AlertA(node-1), AlertA(node-2)]
→ 开始 5min 计时(group_interval)
t=3min 收到 AlertA(instance=node-3) → 同组,暂不发送
t=5min 发送通知 [AlertA(node-3)] → 仅新增部分
t=10min 无新告警,但有未恢复告警
→ repeat_interval 未到,不发送
t=4h repeat_interval 到期
→ 发送重复通知 [AlertA(node-1), AlertA(node-2), AlertA(node-3)]
3.3 分组配置建议
route:
# 按 告警名 + 集群 分组
# 同一集群的同类告警合并为一条通知
group_by: ['alertname', 'cluster', 'service']
group_wait: 30s # 留 30s 收集同组告警
group_interval: 5m # 5 分钟内的告警合并发送
repeat_interval: 4h # 4 小时内不重复发送同一告警
经验法则:
group_by不要包含高基数字段(如instance),否则分组过于碎片化。- Critical 告警
group_wait设为0s,立即发送。 - Warning 告警
group_wait设为5m,等待合并减少噪音。
四、抑制规则
抑制(Inhibition)的核心场景:当高优先级告警触发时,自动静默与之相关的低优先级告警。
4.1 典型场景
- 节点宕机(NodeDown)时,抑制该节点上的所有服务告警
- 网络分区时,抑制因网络不通引发的下游告警
- 数据库主库故障时,抑制依赖该数据库的应用告警
4.2 配置示例
inhibit_rules:
# 场景1:节点宕机时,抑制该节点上的所有其他告警
- source_matchers:
- alertname="NodeDown"
target_matchers:
- alertname!="NodeDown"
equal: ['instance']
# 场景2:Critical 告警抑制同一服务的 Warning 告警
- source_matchers:
- severity="critical"
target_matchers:
- severity="warning"
equal: ['alertname', 'service']
# 场景3:集群不可达时,抑制该集群内的所有告警
- source_matchers:
- alertname="ClusterUnavailable"
target_matchers:
- alertname!="ClusterUnavailable"
equal: ['cluster']
# 场景4:数据库主库宕机,抑制依赖该实例的应用告警
- source_matchers:
- alertname="MySQLMasterDown"
target_matchers:
- alertname=~"App.*"
equal: ['db_instance']
4.3 工作原理
source(NodeDown, instance=node-1, severity=critical)
│
│ 触发抑制
▼
target(CPUHigh, instance=node-1, severity=warning)
│
│ equal: ['instance']
│ instance 相同 → 匹配成功
▼
target 告警被静默
关键字段说明:
source_matchers:触发抑制的告警条件target_matchers:被抑制的告警条件equal:source 和 target 必须在这些标签上值相同才触发抑制
五、静默管理
静默(Silence)用于临时屏蔽特定告警,典型场景是计划内维护(如升级、重启)期间避免告警噪音。
5.1 通过 Web UI 创建静默
访问 Alertmanager Web UI(默认 http://localhost:9093)→ Silences → New Silence:
Matchers:
alertname = NodeHighCpuLoad
instance = node-3
Starts At: 2026-07-10 22:00:00
Ends At: 2026-07-10 23:00:00
Created By: xubaojin
Comment: 计划内维护 - CPU 扩容
5.2 通过 amtool CLI 创建静默
amtool 是 Alertmanager 自带的命令行工具:
# 创建静默(1小时)
amtool silence add \
--comment="计划内维护" \
--author="xubaojin" \
--duration=1h \
alertname=NodeHighCpuLoad \
instance=node-3
# 查看所有静默
amtool silence query \
--alertmanager.url=http://localhost:9093
# 按匹配条件查询
amtool silence query instance=node-3
# 按 ID 过期静默
amtool silence expire <silence-id> \
--alertmanager.url=http://localhost:9093
# 过期所有静默
amtool silence expire $(amtool silence query -o simple | awk '{print $1}')
5.3 通过 API 创建静默
curl -X POST http://localhost:9093/api/v2/silences \
-H "Content-Type: application/json" \
-d '{
"matchers": [
{ "name": "alertname", "value": "NodeHighCpuLoad", "isRegex": false },
{ "name": "instance", "value": "node-3", "isRegex": false }
],
"startsAt": "2026-07-10T22:00:00Z",
"endsAt": "2026-07-10T23:00:00Z",
"createdBy": "xubaojin",
"comment": "计划内维护 - CPU 扩容"
}'
5.4 amtool 常用命令速查
# 查看当前活跃告警
amtool alert query \
--alertmanager.url=http://localhost:9093
# 查看告警路由(检查某告警会匹配到哪个接收者)
amtool config routes test \
--alertmanager.url=http://localhost:9093 \
severity=critical team=sre
# 查看路由树(树形展示)
amtool config routes show \
--alertmanager.url=http://localhost:9093
六、多渠道通知配置
6.1 邮件通知
receivers:
- name: email-team
email_configs:
- to: 'oncall@example.com'
from: 'alertmanager@example.com'
smarthost: 'smtp.example.com:587'
auth_username: 'alertmanager@example.com'
auth_password: 'YOUR_SMTP_PASSWORD'
auth_secret: 'YOUR_SMTP_PASSWORD'
auth_identity: 'alertmanager@example.com'
require_tls: true
headers:
Subject: '{{ .Status | toUpper }} - {{ .CommonLabels.alertname }}'
send_resolved: true
6.2 企业微信 Webhook
receivers:
- name: wecom-team
webhook_configs:
- url: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_WECOM_KEY'
send_resolved: true
max_alerts: 0
企业微信 Webhook 要求特定的消息格式,通常需要部署一个中间转发服务(如 prometheus-webhook-dingtalk 或自定义适配器)将 Alertmanager 的默认 JSON 转为企业微信格式。
企业微信消息模板适配器示例(Go):
package main
import (
"encoding/json"
"fmt"
"net/http"
"bytes"
"github.com/prometheus/alertmanager/template"
)
type WecomMessage struct {
MsgType string `json:"msgtype"`
Markdown struct {
Content string `json:"content"`
} `json:"markdown"`
}
func handler(w http.ResponseWriter, r *http.Request) {
var data template.Data
json.NewDecoder(r.Body).Decode(&data)
content := fmt.Sprintf(
"## 告警通知\n"+
"**状态**: %s\n"+
"**告警数**: %d\n"+
"**详情**:\n",
data.Status, len(data.Alerts),
)
for _, alert := range data.Alerts {
content += fmt.Sprintf(
"- **%s**: %s\n",
alert.Labels["alertname"],
alert.Annotations["summary"],
)
}
msg := WecomMessage{MsgType: "markdown"}
msg.Markdown.Content = content
payload, _ := json.Marshal(msg)
http.Post(
"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
"application/json",
bytes.NewReader(payload),
)
w.WriteHeader(http.StatusOK)
}
func main() {
http.HandleFunc("/wecom", handler)
http.ListenAndServe(":8060", nil)
}
6.3 钉钉 Webhook
receivers:
- name: dingtalk-team
webhook_configs:
- url: 'http://localhost:8060/dingtalk/webhook1/send'
send_resolved: true
钉钉同样需要消息格式适配,推荐使用 prometheus-webhook-dingtalk 项目:
# 启动钉钉 webhook 适配器
prometheus-webhook-dingtalk \
--ding.profile="webhook1=https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN" \
--ding.timeout=5s
七、完整 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_SMTP_PASSWORD'
smtp_require_tls: true
# 模板文件(自定义通知模板)
templates:
- '/etc/alertmanager/templates/*.tmpl'
# 路由树
route:
receiver: default
group_by: ['alertname', 'cluster', 'service']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
# Critical → 立即电话+企业微信
- matchers:
- severity="critical"
receiver: critical-notify
group_wait: 0s
repeat_interval: 1h
continue: true
# Warning → 企业微信
- matchers:
- severity="warning"
receiver: warning-notify
group_wait: 2m
# DBA 团队告警
- matchers:
- team="dba"
receiver: dba-notify
group_wait: 1m
# Info 级别 → 仅存档不发通知
- matchers:
- severity="info"
receiver: null
# 抑制规则
inhibit_rules:
# 节点宕机 → 抑制该节点上的所有其他告警
- source_matchers:
- alertname="NodeDown"
target_matchers:
- alertname!="NodeDown"
equal: ['instance']
# Critical 抑制同服务 Warning
- source_matchers:
- severity="critical"
target_matchers:
- severity="warning"
equal: ['alertname', 'service']
# 集群不可达 → 抑制该集群所有告警
- source_matchers:
- alertname="ClusterUnavailable"
target_matchers:
- alertname!="ClusterUnavailable"
equal: ['cluster']
# 接收者定义
receivers:
- name: default
email_configs:
- to: 'oncall@example.com'
send_resolved: true
- name: critical-notify
webhook_configs:
- url: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_WECOM_KEY'
send_resolved: true
email_configs:
- to: 'critical-oncall@example.com'
send_resolved: true
- name: warning-notify
webhook_configs:
- url: 'http://localhost:8060/dingtalk/webhook1/send'
send_resolved: true
- name: dba-notify
email_configs:
- to: 'dba@example.com'
send_resolved: true
webhook_configs:
- url: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=DBA_WECOM_KEY'
send_resolved: true
- name: null
# 空接收者,丢弃告警
八、高可用部署
Alertmanager 支持多实例 HA 部署,通过 Gossip 协议同步告警状态和静默信息:
# 启动 3 节点 HA 集群
alertmanager \
--config.file=/etc/alertmanager/alertmanager.yml \
--storage.path=/var/lib/alertmanager \
--web.listen-address=:9093 \
--cluster.peer=alertmanager-1:9094 \
--cluster.peer=alertmanager-2:9094 \
--cluster.peer=alertmanager-3:9094 \
--cluster.listen-address=0.0.0.0:9094
在 Prometheus 侧配置多个 Alertmanager 地址实现故障切换:
# prometheus.yml
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager-1:9093
- alertmanager-2:9093
- alertmanager-3:9093
Prometheus 会向所有 Alertmanager 发送告警,各实例通过 Gossip 协议去重,确保最终只有一个实例发送通知。
总结
Alertmanager 的配置核心是围绕三个问题展开的:
- 谁应该收到告警? → 路由树(
route+matchers) - 如何减少告警噪音? → 分组(
group_by)+ 抑制(inhibit_rules)+ 静默(Silence) - 告警如何送达? → 接收者(
receivers)+ 通知渠道
一份好的 Alertmanager 配置应该让值班人员在正常情况下几乎收不到告警(因为问题被提前消除了),在异常情况下只收到精确定位、信息完整、没有重复的告警。记住一个原则:告警不是越多越好,而是越准越好。
更多详情请参阅 Prometheus 官方文档 — Alertmanager
参考资料与致谢
本文在撰写过程中参考了以下资料,感谢原作者的贡献:
- Prometheus 官方文档 — Alertmanager — Prometheus 官方,参考了Prometheus 官方文档 — Alertmanager相关内容
- prometheus-webhook-dingtalk — GitHub 开源社区,参考了prometheus-webhook-dingtalk相关内容