一、概述
1.1 背景介绍
告警系统的失败往往不是"没告警",而是"告警太多"。当误报与无效告警占据值班注意力时,团队会产生典型的告警疲劳:真正的事故告警被淹没,响应变慢,MTTR 上升,最后变成"告警系统自己成为事故源"。
Prometheus + Alertmanager 是事实标准,但在很多组织里,告警规则长期处于以下状态:
- 规则来源于个人经验,缺少 SLO/业务语义,无法解释"为什么这条告警重要"
- 规则过度依赖正则与复杂标签匹配,维护困难、性能差、变更风险高
- 缺少测试与回放,规则变更靠"上线观察",造成误报/漏报
LLM 的价值不在于"自动写 PromQL",而在于它能把"散落的经验"结构化:将规则与上下文(服务拓扑、SLO、历史事故、仪表盘、日志模式)一起输入,输出更符合 SRE 思维的告警设计,并给出可执行的验证与回滚路径。
1.2 技术特点
特点一:SLO 驱动而非阈值驱动
从"CPU > 80% 就告警"转向"错误预算消耗过快就告警",减少噪声并更贴近用户体验。
特点二:规则可测试(Rule-as-Code + 回放评估)
用 promtool test rules 或历史数据回放,在上线前量化评估误报/漏报风险。
特点三:LLM 辅助"重构与解释"
让模型做:规则解读、反模式识别、重构建议、参数解释、生成测试用例草案;最终上线仍以数据与门禁为准。
1.3 适用场景
- 场景一:告警疲劳治理(降噪、分级、抑制、聚合、路由)
- 场景二:SLO/错误预算体系落地(多窗口燃尽率告警)
- 场景三:PromQL 规则重构与性能优化(降低计算开销与标签基数风险)
1.4 环境要求
| 组件 | 版本要求 | 说明 |
|---|---|---|
| Prometheus | 2.4x+ | 支持现代规则与查询能力 |
| Alertmanager | 0.2x+ | 路由、抑制、静默与分组能力 |
| promtool | 与 Prometheus 同版本 | 用于规则校验与测试 |
| CI 执行环境 | Linux/容器 | 用于在合并前跑规则校验与测试 |
| LLM 服务 | 内部或外部 | 仅作为"规则重构助手",不可直接自动上线 |
二、详细步骤
2.1 准备工作
2.1.1 系统检查
promtool --version
curl -fsS http://<prometheus-host>:9090/-/healthy
curl -fsS http://<alertmanager-host>:9093/-/healthy2.1.2 安装依赖
# 获取 promtool(通常随 Prometheus 发布包提供)
promtool --help
# 可选:用于回放/分析的工具
sudo apt update && sudo apt install -y jq ripgrep2.2 核心配置
2.2.1 盘点现状:把"告警噪声"量化出来
先定义你要优化的指标,否则"误报率降了多少"无法度量。建议至少统计:
- 告警总量、告警去重后事件量(按
fingerprint聚合) - 页面告警(page)与通知告警(ticket/info)的比例
- 告警关联真实事故的比例(需要和工单/复盘对齐)
- Top N 噪声告警(占比、触发时间段、常见触发原因)
# 示例:从 Alertmanager API 拉取当前活跃告警(按需替换地址)
curl -fsS http://<alertmanager-host>:9093/api/v2/alerts | jq '.[].labels.alertname' | sort | uniq -c | sort -nr | head说明:量化阶段往往会发现:一小部分规则贡献了大部分噪声。优先处理 Top 噪声告警,比"全面重写"更具性价比。
2.2.2 规则重构策略:从"阈值堆砌"到"SLO 告警"
把规则分成 3 类,并采用不同策略:
| 规则类型 | 策略 |
|---|---|
| 用户体验类(优先 SLO) | 错误率、延迟分位、可用性,建议用错误预算燃尽率(多窗口) |
| 容量与资源类 | CPU/内存/磁盘/连接数,建议用"趋势 + 余量"而不是单点阈值 |
| 组件健康类 | 实例存活、关键依赖不可达,建议精简直接,避免过度计算 |
多窗口燃尽率告警示例(需要结合 SLO 目标与错误预算定义调整):
# 文件路径:rules/slo.yml(示例)
groups:
- name: slo-burnrate
rules:
- alert: ApiErrorBudgetBurningFast
expr: |
(
sum(rate(http_requests_total{job="api",status=~"5.."}[5m]))
/
sum(rate(http_requests_total{job="api"}[5m]))
) > 0.02
and
(
sum(rate(http_requests_total{job="api",status=~"5.."}[1h]))
/
sum(rate(http_requests_total{job="api"}[1h]))
) > 0.01
for: 2m
labels:
severity: page
team: sre
annotations:
summary: "API 错误预算消耗过快"
runbook: "<你的 Runbook 地址>"说明:这类告警的目标是减少噪声:短窗口捕捉突发,长窗口防止短抖动误报。阈值必须以 SLO/错误预算为依据,而不是"经验值"。
2.2.3 用 LLM 辅助重构:提示词与门禁
LLM 参与告警重构建议采用"输入充分上下文 + 输出可验证产物"的模式:
输入建议包含:
- 现有规则(PromQL、for、labels、annotations)
- 业务 SLO/SLI 定义(如果没有,就输出"缺失项清单")
- 历史告警样本(触发时段、对应指标走势)
- 复盘结论(哪些告警是有效信号,哪些是噪声)
输出必须包含:
- 重构后的规则
- 变更理由(对应反模式)
- 可执行验证方案(如何回放、如何灰度、如何回滚)
提示词示例:
你是资深 SRE。以下是一个 Prometheus 告警规则与其历史触发情况。
请输出:
1) 该规则是否属于告警反模式(说明原因)
2) 重构后的规则(PromQL + for + labels/annotations)
3) 验证方案(promtool 测试、灰度策略、回滚条件)
约束:不要引入无法在 Prometheus 中实现的语法;不要使用不可控的正则;
如果缺少 SLO,请先给出 SLO 建议与缺失项。2.3 启动和验证
2.3.1 上线前验证(强制)
# 规则语法校验
promtool check rules rules/*.yml2.3.2 规则单测(推荐)
# 文件路径:rules/tests/slo_test.yml(示例:promtool test rules)
rule_files:
- ../slo.yml
evaluation_interval: 1m
tests:
- interval: 1m
input_series:
- series: 'http_requests_total{job="api",status="500"}'
values: '0+10x120'
- series: 'http_requests_total{job="api",status="200"}'
values: '0+990x120'
alert_rule_test:
- eval_time: 10m
alertname: ApiErrorBudgetBurningFast
exp_alerts:
- exp_labels:
severity: page
team: srepromtool test rules rules/tests/slo_test.yml预期输出:
- 规则语法通过
- 测试用例在预期时间点触发(或不触发)
- 输出可作为"规则变更门禁"的一部分
三、示例代码和配置
3.1 完整配置示例
3.1.1 主配置文件
# 文件路径:rules/alerts.yml(示例)
groups:
- name: infra
rules:
- alert: NodeDiskWillFillIn24Hours
expr: |
predict_linear(node_filesystem_free_bytes{fstype!~"tmpfs|overlay"}[6h], 24*3600) < 0
for: 30m
labels:
severity: ticket
annotations:
summary: "磁盘空间预计 24 小时内耗尽"
description: "请检查增长最快的目录与日志轮转策略"3.1.2 辅助脚本
#!/bin/bash
# 文件名:tools/check_rules.sh
set -euo pipefail
promtool check rules rules/*.yml
promtool test rules rules/tests/*.yml
echo "rules_ok"3.2 实际应用案例
案例一:把"CPU > 80%"改成"容量风险"告警
场景描述:CPU 高并不一定是事故。更有效的是预测"余量将耗尽",并把告警路由为 ticket(可计划处理),而不是 page。
实现步骤:
- 用趋势指标(如
predict_linear)替代单点阈值 - 为告警补齐 runbook(如何定位占用、如何扩容、如何降级)
- 按严重性分级路由与静默策略(值班不被噪声打爆)
案例二:把"正则堆砌"的错误率告警改为 SLO 燃尽率
场景描述:正则匹配易错且维护成本高。将错误率定义与 SLO/SLI 绑定,配合多窗口燃尽率策略,通常能显著减少误报并提升可解释性。
实现步骤:
- 明确 SLI(请求总量、错误请求)与统计口径
- 设计燃尽率阈值与窗口(短 + 长)
- 上线前回放历史事故与噪声区间,验证触发行为
四、最佳实践和注意事项
4.1 最佳实践
4.1.1 性能优化
优化点一:控制标签基数,避免规则计算炸裂
在规则中对高基数标签做 sum by(...) 聚合,避免每个实例/用户维度都触发告警。
# 查看 Prometheus 规则评估耗时相关指标
curl -fsS http://<prometheus-host>:9090/metrics | rg "prometheus_rule_evaluation_duration_seconds"优化点二:减少正则,优先使用明确标签
正则会提高维护成本与查询开销。标签治理比规则技巧更重要。
优化点三:建立"规则变更门禁"
规则变更必须包含:语法校验、单测、灰度、回滚条件、告警路由评审。
4.1.2 安全加固
安全措施一:变更可追溯与审批
告警规则属于"生产控制面"配置,必须有审批与回滚机制。
安全措施二:告警渠道最小化
page 只发真正影响用户体验的信号;其余进入 ticket 或日报,减少无效中断。
4.1.3 高可用配置
- HA 方案一:双 Alertmanager + 去重,避免单点导致告警丢失或风暴
- HA 方案二:分环境规则(生产/预发/测试隔离),防止测试噪声污染值班
- 备份策略:规则、路由、抑制与静默策略都需要可回滚版本
4.2 注意事项
4.2.1 配置注意事项
警告:不要让 LLM 直接"生成规则并自动上线"。它最多是建议者,最终必须用数据回放与门禁来决定是否进入生产。
- 注意事项一:SLO/SLI 不清晰时,先补齐定义,再谈告警规则
- 注意事项二:任何"减少误报"的改动都可能引入漏报,必须评估二者平衡
- 注意事项三:路由与抑制规则需要同步调整,否则规则再好也会变噪声
4.2.2 常见错误
| 错误现象 | 原因分析 | 解决方案 |
|---|---|---|
| 告警风暴 | 缺少分组/抑制/for 太短 | 调整 Alertmanager group;合理设置for;加抑制规则 |
| 告警漏报 | 聚合过度或阈值过高 | 回放历史事故;分级告警;加入短窗口信号 |
| 查询太慢 | 高基数 + 正则 + 长窗口 | 先聚合再计算;减少正则;用 recording rules |
4.2.3 兼容性问题
- 版本兼容:Prometheus/Alertmanager 版本差异会影响字段与行为,升级需灰度
- 平台兼容:K8s/VM 指标名称与标签差异较大,需要统一采集规范
- 组件依赖:规则依赖的指标一旦重命名/下线,告警会静默失效,需做指标契约管理
五、故障排查和监控
5.1 故障排查
5.1.1 日志查看
# Prometheus 自身日志(路径按部署方式调整)
kubectl -n monitoring logs deploy/prometheus | tail -200
# Alertmanager 日志
kubectl -n monitoring logs deploy/alertmanager | tail -2005.1.2 常见问题排查
问题一:规则不触发
# 直接在 Prometheus Web UI 或 API 查询 expr 对应的 PromQL 是否有数据
curl -G -fsS "http://<prometheus-host>:9090/api/v1/query" --data-urlencode 'query=up'解决方案:排查指标是否存在、标签是否匹配、采集是否断流;必要时为关键指标建立 recording rules 并做契约校验。
5.2 性能监控
5.2.1 关键指标监控
# 建议关注 Prometheus 规则评估耗时与失败率相关指标
curl -fsS http://<prometheus-host>:9090/metrics | rg "prometheus_rule_evaluation"5.2.2 监控指标说明
| 指标名称 | 正常范围 | 告警阈值 | 说明 |
|---|---|---|---|
| 规则评估耗时 | 稳定 | 持续升高 | 可能是标签基数或查询复杂度问题 |
| 规则评估失败 | 接近 0 | > 0 | 表示规则语法或依赖指标异常 |
| 告警事件量 | 稳定 | 突增 | 需要识别告警风暴与噪声来源 |
5.2.3 监控告警配置
groups:
- name: prometheus-self
rules:
- alert: PrometheusRuleEvaluationSlow
expr: histogram_quantile(0.99, sum(rate(prometheus_rule_evaluation_duration_seconds_bucket[5m])) by (le)) > 1
for: 10m
labels:
severity: ticket
annotations:
summary: "Prometheus 规则评估变慢"5.3 备份与恢复
5.3.1 备份策略
#!/bin/bash
# 备份脚本示例:规则与路由配置
set -euo pipefail
ts="$(date +%Y%m%d-%H%M%S)"
tar -czf "/backup/prom-rules-$ts.tgz" rules/ alertmanager/
echo "backup_ok=$ts"5.3.2 恢复流程
- 回滚规则文件:恢复到上一个稳定版本
- 校验与加载:
promtool check rules后再 reload - 观察指标:确认规则评估耗时与告警量恢复正常
六、总结
6.1 技术要点回顾
- 要点一:告警治理先量化,再优化;优先处理 Top 噪声告警
- 要点二:SLO 驱动告警比阈值堆砌更贴近用户体验,也更抗抖动
- 要点三:LLM 可用于重构与解释,但上线必须走"校验+测试+灰度+回滚"门禁
- 要点四:告警系统的可靠性来自"规则 + 路由 + 抑制 + 人的流程"共同作用
6.2 进阶学习方向
方向一:SLO/错误预算体系
- 学习资源:SRE 相关经典实践(SLO/SLI/Error Budget)
- 实践建议:先选 1~2 条关键用户旅程落地 SLO,再扩展到全服务
方向二:规则测试与回放平台
- 学习资源:promtool 测试、历史数据回放
- 实践建议:把规则测试纳入 CI 门禁,降低变更风险
方向三:告警降噪工程
- 学习资源:Alertmanager 分组/抑制/静默、事件聚合
- 实践建议:从"Page 只留用户体验信号"开始治理
6.3 参考资料
- Prometheus 文档 - 查询、规则与最佳实践
- Alertmanager 文档 - 路由、分组、抑制与静默
- SRE Workbook - SLO/告警策略(概念与方法论)
附录
A. 命令速查表
# 规则语法校验
promtool check rules rules/*.yml
# 规则单测执行
promtool test rules rules/tests/*.yml
# 查看当前活跃告警
curl -fsS http://<alertmanager-host>:9093/api/v2/alerts | jq '.[].labels.alertname'B. 配置参数详解
| 参数 | 说明 |
|---|---|
for | 抖动过滤器,不是"延迟告警",而是减少误报的重要手段 |
severity | 告警分级的基础字段,必须与路由策略一致 |
annotations.runbook | 让告警可执行,减少值班人员的上下文切换成本 |
C. 术语表
| 术语 | 英文 | 解释 |
|---|---|---|
| 服务等级目标 | SLO | 用户体验底线,用于约束告警与变更节奏 |
| 错误预算 | Error Budget | 可用性目标允许的失败额度,燃尽率告警以此为依据 |
| 告警疲劳 | Alert Fatigue | 告警过载导致团队对告警不再敏感,响应变慢 |