参考资料
Alertmanager | Prometheus

Alertmanager | Prometheus
Prometheus project documentation for Alertmanager
Alertmanager 核心概念:Grouping, Inhibition, Silences
- Grouping(分组):将具有相似特征的多个告警合并为一条通知,避免“告警风暴”
- 典型场景:
- 网络分区导致数百个服务实例无法连接数据库 → 每个实例触发一个告警
- 用户只需收到 1 条通知,但能查看所有受影响实例
- Inhibition(抑制):当某个“高级别”告警触发时,自动抑制其他“低级别”或冗余告警
- 典型场景:
- “整个集群不可达”告警触发 → 抑制该集群内所有主机、服务、磁盘等子系统告警
- Silences(静音):临时手动屏蔽符合特定条件的告警(例如维护期间)
- 使用场景:
- 计划内维护、已知问题排查期、测试环境调试
Alertmanager 支持基于 Gossip 协议( Hashicorp Memberlist 库)的集群模式
通过 --cluster-* 标志进行配置 Alertmanager 集群
--cluster.listen-address string:集群监听地址- 默认值
0.0.0.0:9094 - 空字符串将禁用 HA 模式
--cluster.advertise-address string:集群通告地址
--cluster.peer value:初始对等节点- 可重复,每个额外节点添加一次
--cluster.peer-timeout value:对等节点超时时间- 默认
"15s"
--cluster.peers-resolve-timeout value:对等节点解析超时时间- 默认
"15s"
--cluster.gossip-interval value:集群消息传播速度- 默认
"200ms"
--cluster.pushpull-interval value:值越小收敛速度越快,但会占用更多带宽- 默认
"1m0s"
--cluster.settle-timeout value:在评估通知前等待集群连接就绪的最大时间
--cluster.tcp-timeout value:TCP 连接、读取和写入的超时时间- 默认
"10s"
--cluster.probe-timeout value:在标记节点为不健康前等待 ACK 的时间- 默认
"500ms"
--cluster.probe-interval value:随机节点探测之间的间隔- 默认
"1s"
--cluster.reconnect-interval value:尝试重新连接丢失的对等节点之间的间隔- 默认
"10s"
--cluster.reconnect-timeout value:尝试重新连接到丢失的对等节点的持续时间- 默认
"6h0m0s"
--cluster.label value:唯一标识集群,并能在发送 Gossip 消息时防止交叉通信问题- 可选字符串,包含在每个数据包和流中
- 默认:
""
Alertmanager 集群架构
- 去中心化设计
- 集群由多个独立的 Alertmanager 实例组成,每个实例独立接收告警、处理并发送通知
- 所有实例通过点对点 Gossip 网状网络连接,无主从之分
- 数据流向
- 多个 Prometheus 服务器将告警独立推送到各个 Alertmanager 实例
- 实例间通过 Gossip 协议同步状态
- 各实例独立将处理后的通知发送给接收方(Receivers)
Gossip 协议实现成员管理和状态复制
- 成员管理
- 自动发现:通过配置的初始对等节点列表,自动发现集群所有成员。
- 健康检查与故障检测:默认每秒探测,标记失效节点,支持重加入。
- 状态复制
- 复制三类关键状态以实现集群协同:
- 静默(Silences):增删改操作广播同步。
- 通知日志(Notification log):发送记录,用于去重。
- 成员变更:节点加入、离开、故障事件。
- 最终一致性:在网络稳定后,所有节点状态将最终一致
Gossip 稳定机制
- 当一个 Alertmanager 启动或重新加入集群时,会等待 Gossip “稳定”再开始处理通知,防止基于不完整状态做出错误决策
- 稳定条件
- 对等节点数量在连续3次检查中保持稳定(默认检查间隔为
push-pull间隔) - 或达到配置的超时时间。
- 等待期间行为:实例已接收并存储告警,但延迟通知处理,直到状态同步完成
Alertmanager 集群中的通知流水线
- 确保至少一次送达,同时避免不必要的重复发送
通知流水线分为分发器和通知期两个阶段
- 分发器阶段(Dispatcher Stage):
- 匹配路由规则
- 在路由内创建/查找告警聚合组
- 根据组等待时间(
group_wait)或组间隔(group_interval)进行节流控制
- 通知器阶段(Notifier Stage) - 包含核心HA逻辑:
- 等待Gossip稳定:确保集群状态(静默、成员等)同步完成
- 多重过滤:按顺序抑制、静默、时间等条件过滤告警
- 基于节点序号的错峰等待:错开各实例的发送时间以协调去重
- 基于通知日志的去重:检查历史记录,决定是否发送
- 发送与重试:执行通知,并重试临时性故障
- 更新通知日志:记录发送历史,并通过Gossip同步
集群特有的通知器阶段关键步骤
- Gossip稳定等待:在首次发送前等待,目的是让集群状态(静默、成员、通知日志)充分同步
- 基于节点序号的错峰等待
- 目的:防止所有实例同时发送告警,为去重留出协调时间窗口。
- 计算方式:
等待时间 = 节点序号 × 节点超时(peer_timeout)。 - 节点序号:按节点名称字母顺序排序后,确定自身在列表中的位置。
- 示例:3节点集群,
peer_timeout=15秒。 am-1(位置0):等待0秒→ 最先发送。am-2(位置1):等待15秒。am-3(位置2):等待30秒→ 可能在等待期间看到日志记录,从而抑制自身发送
- 基于通知日志的去重
- 机制:查询共享的、通过Gossip同步的通知日志(
nflog),检查近期是否已发送过相同告警 - 触发重新发送的条件(满足任一即可):
- 告警状态变化:新增或恢复的告警
- 重复间隔到期:超过预设的重复通知间隔(
repeat_interval) - 否则:抑制本次发送(完成去重)
Alertmanager 集群中的静默(Silence)管理机制
- 静默包含:StartsAt、EndsAt(生效时间)、ExpiresAt(清理时间)、UpdatedAt(解决冲突)
静默是集群中的一等复制状态,所有实例通过Gossip协议同步,提供最终一致性的统一视图
- 用户可访问任意实例查看、创建、更新、删除静默
- 删除操作实质是“立即过期” + Gossip广播
- 所有操作会自动同步到整个集群,提供统一的运维体验
静默同步流程
- 创建/更新
- 在任何实例上操作 → 存储到本地状态映射。
- 序列化(Protobuf)并通过Gossip广播给所有节点。
- 接收与合并
- 采用基于时间戳(UpdatedAt)的最后写入优先策略解决冲突。
- 接收方比较时间戳,只接受更新的版本。
- 索引更新
- 各实例更新本地匹配器缓存,以实现快速告警匹配
- 每个实例独立判断状态与清理静默
- 根据本地时间判断静默状态(待生效/活跃/已过期)。
- 独立清理超过保留期的过期静默(无需Gossip),依靠算法保证各节点决策最终一致
Alertmanager 集群采用“故障开放”策略处理脑裂(网络分区)
- 优先确保告警被发送(可能重复),而不是丢失告警
网络分区场景下的行为
- 分区前:三个Alertmanager实例(AM-1, AM-2, AM-3)组成统一集群
- 分区后:
- 分区A:仅AM-1。它立即发送通知,无法与其他实例去重。
- 分区B:包含AM-2和AM-3。AM-2立即发送通知,AM-3检测到重复后抑制自身通知
- 结果:两个分区各发送一次通知,导致重复告警。这是为确保告警可达性而接受的合理副作用
分区恢复后的处理
- Gossip协议重新发现所有节点。
- 各实例的通知日志通过类似CRDT的机制合并(基于时间戳)
- 静默规则在分区期间独立创建的)会同步到所有节点
- 集群恢复全局去重能力
Alertmanager 集群运维
不要在 Prometheus 及其 Alertmanager 之间进行流量负载均衡
- 将 Prometheus 指向所有 Alertmanager 的列表提供以下保障
- 没有单点故障:负载均衡器会引入单点故障
- 冗余机制:即使一个警报管理器发生故障,其他管理器仍能收到警报
- 独立处理:每个实例独立评估路由、分组和去重
集群规模设计
- 任何 N 个实例最多可以容忍 N-1 个故障
- Alertmanager 使用没有法定人数或投票的 gossip 协议,与基于共识的系统(etcd、Raft)不同,奇数与偶数集群大小没有区别
- 典型部署:
- 2-3 个实例 - 常见于单数据中心生产部署
- 4-5 个实例 - 多数据中心或高度关键环境
监测集群健康状况的关键指标
持久化和重启后处理流程
- 警报本身不会持久保存 - Prometheus 会定期重新发送触发警报
- 持久化内容
- Silences - 存储在快照文件中(默认:
data/silences) - 通知日志 - 存储在快照文件中(默认:
data/nflog)
- 发生重启时
- 实例从磁盘加载静默和通知日志
- 加入集群并通过 gossips 协议与对等节点(peers)协商
- 合并从对等节点接收到的状态(时间戳较新的状态生效)
- gossips 协商完毕后开始处理通知
基于 Go 模板语言的可复用 Alertmanager 通知模板
参考资料
Notification template reference | Prometheus

Notification template reference | Prometheus
Prometheus project documentation for Notification template reference
Notification template examples | Prometheus

Notification template examples | Prometheus
Prometheus project documentation for Notification template examples
- 发送给接收者的通知是通过模板构建的
- 与 Prometheus 中的模板(告警规则和控制台页面)有所不同
数据结构
名称(Name) | 类型 | 说明(Notes) |
Receiver | string | 定义接收通知的目标接收器名称(如 slack、email 等) |
Status | string | 若至少有一个告警处于触发状态,则值为 firing;否则为 resolved |
Alerts | Alert | 本组中所有告警对象的列表(见下文) |
GroupLabels | KV | 这些告警被分组所依据的标签集合 |
CommonLabels | KV | 所有告警共有的标签集合 |
CommonAnnotations | KV | 所有告警共有的注解集合,通常用于提供关于告警的更详细的附加信息 |
ExternalURL | string | 指向发送此通知的 Alertmanager 实例的回链地址(Backlink) |
Alerts 类型包含一个用于通知模板的警报
Alerts.Firing返回此组中当前正在触发的警报对象列表
Alerts.Resolved返回此组中已解决的警报对象列表
名称 | 类型 | 说明(Notes) |
Status | string | 指明告警当前是已恢复( resolved)还是正在触发(firing) |
Labels | KV | 附加到该告警的一组标签(键值对),用于标识和分组 |
Annotations | KV | 该告警的一组注解(键值对),通常用于提供更详细的、非标识性的信息(如描述、运行手册链接等) |
StartsAt | time.Time | 告警开始触发的时间。如果未指定,Alertmanager 会将其设为当前时间 |
EndsAt | time.Time | 仅在已知告警结束时间时设置;否则,Alertmanager 会将其设为从上次收到该告警起经过一个可配置的超时周期后的时间。 |
GeneratorURL | string | 指向触发此告警的源头实体的回链地址(例如 Prometheus 的查询链接) |
Fingerprint | string | 可用于唯一标识该告警的指纹(基于标签计算得出) |
KV 类型代表一组键/值字符串对,用于表示标签和注释
KV 方法
Pairs键/值字符串对的列表
名称 | 参数 | 返回值 | 说明(Notes) |
SortedPairs | - | Pairs | 返回按键排序后的键值对列表。 |
Remove | []string | KV | 返回一个移除了指定键的新键值映射副本 |
Names | - | []string | 返回该 LabelSet 中所有标签的键名列表 |
Values | - | []string | 返回该 LabelSet 中所有标签的值列表 |
包含两个注解的注解示例
string 类型函数
- 除此之外还提供 Go 模板引擎的函数
名称 | 参数 | 描述(Description) |
date | string, time.Time | 以指定格式返回时间的文本表示
格式说明请参考 pkg.go.dev/time |
humanizeDuration | number 或 string | 返回一个可读性良好的持续时间字符串;若发生错误,也会返回错误信息 |
join | sep string, s []string | 等同于 strings.Join:将字符串切片 s 中的元素连接成一个字符串,元素之间用分隔符 sep 连接。(注:参数顺序已调整,便于在模板中使用管道操作。) |
match | pattern, string | 等同于 Regexp.MatchString:使用正则表达式匹配字符串 |
reReplaceAll | pattern, replacement, text | 等同于 Regexp.ReplaceAllString:执行无锚点的正则表达式替换 |
safeHtml | text string | 等同于 html/template.HTML:将字符串标记为 HTML 内容,无需自动转义 |
safeUrl | text string | 等同于 html/template.URL:将字符串标记为 URL,无需自动转义 |
since | time.Time | 等同于 time.Since:返回从给定时间到当前系统时间经过的持续时间 |
stringSlice | ...string | 将传入的多个字符串参数转换为字符串切片( []string) |
title | string | 等同于 strings.Title:将每个单词的首字母大写 |
toJson | any | 等同于 json.Marshal:返回该值的 JSON 编码字符串 |
toLower | string | 等同于 strings.ToLower:将所有字符转换为小写 |
toUpper | string | 等同于 strings.ToUpper:将所有字符转换为大写 |
trimSpace | string | 等同于 strings.TrimSpace:移除字符串首尾的空白字符 |
tz | string, time.Time | 将时间转换为指定时区的时间 |
urlUnescape | text string | 等同于 url.QueryUnescape:对包含 % 编码的 URL 进行解码 |
Alertmanager 通知模板样例
假设存在以下 alert
配置可复用的模板
vim /alertmanager/template/myorg.tmpl
假设有自定义 Slack 通知的 Alertmanager 配置
通过命令行标志和配置文件配置 Alertmanager
- 查看可用命令行标志
alertmanager -h
Alertmanager 全局配置平台相关配置
smtp 配置 global.smtp_*
jira 配置 global.jira_api_*
微信配置 global.wechat_api_*
telegram 配置 global.telegram_api_*
slack 配置 global.slack_api_*
开源协作平台 rocketchat 配置 global.rocketchat_*
远程协作平台 Webex 配置 global.webex_api_*
事件管理平台 PagerDuty 配置 global.pagerduty_*
事件管理平台 Opsgenie 配置 global.opsgenie_api_*
事件管理平台 VictorOps 配置 global.victorops_api_*
Alertmanager 配置文件全局配置和文件配置
global.http_config.<http_config> HTTP 客户端配置
- 参考另一文章 Prometheus 命令行工具
promtool promtool的 HTTP 客户端配置文件- 基本涉及
http_config的都大差不差
time_intervals.<time_interval> 配置定义一个命名的时间间隔
- 在路由树中引用该时间间隔,以便在一天中的特定时间静音/激活特定路由
<matcher> 配置用于将告警与路由、静音和抑制规则进行匹配的标签匹配器
- 目前 Prometheus 增加了对标签和指标的 UTF-8 支持
alertmanager 标签匹配器目前支持三种运行模式
- Fallback 模式(默认):兼容新旧匹配器,匹配器首先会被解析为 UTF-8,遇到不兼容的内容会自动回退到 Classic 匹配器继续工作并记录警告日志
- 警告会提供如何将匹配器从 Classic 匹配器更改为 UTF-8 匹配器的建议
- 匹配器在两个解析器中都有效,但解析结果不同
- 存在冲突时将使用 Classic 匹配器并记录警告日志
- 后续版本可能会改为默认 UTF-8 严格模式
极少数情况下,配置可能会导致 UTF-8 匹配器和 Classic 匹配器之间出现冲突
- UTF-8 严格模式:仅支持新式 UTF-8 匹配器,拒绝传统语法
--enable-feature="utf8-strict-mode"- alertmanager 全新安装建议启用 UTF-8 严格模式
- Classic 模式:Alertmanager 0.26.0 及更早版本
--enable-feature="classic-mode"
- 使用 amtool 验证配置文件是否兼容 UTF-8 严格模式
amtool check-config config.yml --enable-feature="utf8-strict-mode"
UTF-8 匹配器由三个标记(tokens)组成
- 标签名称:可以是未加引号的字面量,也可以是用双引号括起的字符串
- 未加引号的字面量可以包含除保留字符以外的所有 UTF-8 字符
- 保留字符包括
{ } ! = ~ , \ " ' ` - 双引号字符串可以包含所有 UTF-8 字符,支持 UTF-8 代码点,没有保留字符
- 双引号和反斜杠字面量必须使用单个反斜杠进行转义
- 如
\d+,反斜杠必须转义为"\\d+"
- 操作符:
=、!=、=~或!~之一
- 标签值或正则表达式:可以是未加引号的字面量,也可以是用双引号括起的字符串
Classic 匹配器由三个标记(tokens)组成
- 有效的 Prometheus 标签名称
- 操作符:
=、!=、=~或!~之一,含义与 PromQL 选择器中一致
- 一个 UTF-8 字符串,可选择用双引号括起来,可以是空字符串
- 适用 OpenMetrics 转义规则
\"表示双引号,\n表示换行符,\\表示反斜杠
可以组合匹配器来创建复杂的匹配表达式
- 组合后的匹配器必须全部匹配,整个表达式才能匹配成功
- 表达式
{alertname="Watchdog", severity=~"warning|critical"}将匹配标签为alertname=Watchdog, severity=critical的警报,但不会匹配标签为alertname=Watchdog, severity=none的警报
匹配器样例
以 YAML 列表形式组成的两个匹配器
以简短的 YAML 列表形式组成的两个匹配器
- 最好使用双引号,以避免逗号等特殊字符引起的问题
将两个匹配器放在一个类似 PromQL 的字符串中
- 最好使用单引号
使用 YAML 代码块避免 YAML 中转义和引用规则出现问题
route.<route> 配置定义了路由树中的一个节点及其子节点
- 所有告警都从配置的顶层路由(即根路由)进入路由树,告警会遍历其子节点
- 顶层路由必须匹配所有告警
- 子节点可选的配置参数若未显式设置,则会从父节点继承
- 如果某个匹配的子节点设置了
continue: false,则在该节点匹配后停止继续匹配 - 如果设置了
continue: true,则告警会继续与后续的同级节点进行匹配
- 如果一个告警未匹配当前节点的任何子节点,将按照当前节点的配置参数进行处理
路由配置样例
inhibit_rules.<inhibit_rule> 允许在存在另一组告警时,静音当前一组告警
- 在存在匹配“源告警”(source alert)的情况下,静音所有匹配“目标告警”(target alert)条件的告警
源告警和目标告警必须在 equal 列表中指定的所有标签上具有相同的值
- 缺失的标签与值为空的标签被视为等价
- 如果
equal列表中的所有标签在源告警和目标告警中均不存在,该抑制规则仍然会生效
- 防止告警自我抑制:若某条告警同时匹配规则中的目标条件和源条件,则它不能被其他同样同时匹配目标和源条件的告警(包括它自己)所抑制
- 建议在配置时确保目标匹配器和源匹配器互不重叠
receivers.<receiver> 配置定义通知目标(即“接收器”)
receivers.<receiver_configs>.<receiver_configs> 接收器平台集成相关配置
- 只引用部分,其余详见对应文档
<tmpl_string>表示该字段支持 Go 模板语法
global.*表示从全局配置继承默认值
邮件配置 email_configs.<email_config>
<tmpl_string>表示该字段支持 Go 模板语法,可在运行时动态渲染
global.*表示从全局 SMTP 配置继承默认值
webhook 配置 webhook_configs.<webhook_config>
- 有一些与特定平台的 webhook 集成
Alertmanager 目前以以下 JSON 格式向配置的端点发送 HTTP POST 请求
即时通讯工具
sns 配置 sns_configs.<sns_config>
topic_arn、phone_number和target_arn三者中至少需指定一个,用于确定消息投递目标
微信配置 wechat_configs.<wechat_config>
slack 配置 slack_configs.<slack_config>
可以通过 webhook 或者 bot 令牌传入
- webhook:
api_url必须设置为传入 webhook 的 URL,或者写入api_url_file中引用的文件
- bot 令牌:
api_url为https://slack.com/api/chat.postMessage,Bot 令牌必须设置为http_config中的授权凭据,并且channel必须包含要发送通知的频道名称或频道 ID
actions和fields分别用于定义交互按钮和消息中的详细信息字段
<action_config> 在 Slack API 文档中针对消息附件和互动消息进行了说明
Formatting message text | Slack Developer Docs
Formatting message text | Slack Developer Docs
For user instructions on message formatting in your Slack client, refer to this Help Center article.
Legacy interactive message field guide | Slack Developer Docs
Legacy interactive message field guide | Slack Developer Docs
The interactive message framework layers atop typical Slack messages and makes heavy use of message formatting and attachments.
<action_confirm_field_config> 在 Slack API 文档中进行了说明
<field_config> 在 Slack API 文档中进行了说明
telegram 配置 telegram_configs.<telegram_config>
discord_configs.<discord_config>
rocketchat_configs.<rocketchat_config>
webex_configs.<webex_config>
mattermost_configs.<mattermost_config>
IT 服务管理(ITSM)与事件响应平台
jira 配置 jira_configs.<jira_config>
JIRA API 文档
The Jira Cloud platform REST API
The Jira Cloud platform REST API
The Jira REST API enables you to interact with Jira programmatically. Use this API to build apps, script interactions with Jira, or develop any other type of integration. This page documents the REST resources available in Jira Cloud, including the HTTP response codes and example requests and responses.
- 此集成仅在 Jira Cloud 实例上测试过
labels字段是添加到问题的标签列表,支持模板表达式
<jira_field> 根据 JIRA 问题字段类型的不同,其值必须以不同的方式提供
opsgenie_configs.<opsgenie_config>
pagerduty_configs.<pagerduty_config>
incidentio_configs.<incidentio_config>
victorops_configs.<victorops_config>
microsoft teams
msteams_configs.<msteams_config>
msteamsv2_configs.<msteamsv2_config>
pushover_configs.<pushover_config>
Alertmanager 配置文件 tracing 配置
Alertmanager 命令行工具 amtool
安装 amtool 二进制工具
export AM_VER=0.30.0
curl -Lo alertmanager.tar.gz https://github.com/prometheus/alertmanager/releases/download/v$AM_VER/alertmanager-$AM_VER.linux-amd64.tar.gz
tar -xzf alertmanager.tar.gz --wildcards "*/amtool" --strip-components=1
chmod +x ./amtool
mv ./amtool /usr/local/bin/
amtool 配置文件
在以下路径查找配置文件
$HOME/.config/amtool/config.yml
/etc/amtool/config.yml
配置文件样例
amtool config show查看当前配置
amtool check-config [<check-files>...]测试配置文件是否有效
amtool cluster show查询集群状态和 peers 节点
amtool alert 添加或查询 alert
amtool alert add [<labels>...]添加 alert
amtool alert query [<matcher-groups>...] 查询当前触发的 alert
amtool -o extended alert query alertname=~"Test.*" instance=~".+1"
amtool silence 管理 silence
amtool silence add [<matcher-groups>...] 添加 silence 以关闭 alert
amtool silence add alertname="Test_Alert" instance=~".+0"
amtool silence import [<input-file>]从文件导入 silence
amtool silence update [<update-ids>...]更新 silence
amtool silence expire [<silence-ids>...] 消除 silence
amtool silence expire b3ede22e-ca14-4aa0-932c-ca2f3445f926
amtool silence expire $(amtool silence query -q instance=~".+0")- 消除匹配的 silence
amtool silence expire $(amtool silence query -q)- 消除所有 silence
amtool silence query [<matcher-groups>...] 查询 silence
amtool silence query instance=~".+0"
amtool template render --template.glob=TEMPLATE.GLOB --template.text=TEMPLATE.TEXT 测试模板的渲染
amtool template render --template.glob='/foo/bar/*.tmpl' --template.text='{{ template "slack.default.markdown.v1" . }}'
amtool config routes 可视化或测试配置路由
amtool config routes show 以文本树状视图的形式可视化配置路由
amtool config routes --alertmanager.url=http://localhost:9090
amtool config routes test [<labels>...] 通过传递警报标签集来测试路由
amtool config routes test --config.file=doc/examples/simple.yml --tree --verify.receivers=team-X-pager service=database owner=team-X
- Author:白鸟3
- URL:https://blog.kun2peng.top/operation/prometheus_alertmanager
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
