【架构实战】Prometheus监控:告警规则设计与降噪

发布时间:2026/7/21 22:08:34
【架构实战】Prometheus监控:告警规则设计与降噪 一、告警风暴被狼来了消耗的团队去年我们团队经历过一段黑暗时期。Prometheus配置了200多条告警规则结果一个月内产生了3万条告警。平均每天1000条告警群里消息刷屏运维同学被叫醒的次数比看手机的次数还多。真正的故障反而被淹没在告警海洋中——某天晚上核心服务挂掉但告警没发出来因为负责发的那个人的手机被之前的告警刷到没电了。更讽刺的是一个月后我们统计发现真正需要处理的告警不到5%其余95%都是噪音。这就是典型的告警疲劳Alert Fatigue阈值设置不合理告警级别混乱没有降噪机制告警没有行动指引痛定思痛我们重做了告警体系3万条告警降到每月300条95%是有效告警。今天就分享这套告警规则设计和降噪的实战经验。二、告警的本质信号与噪音的博弈2.1 告警的核心目标好的告警应该满足及时性故障发生后分钟内通知到人准确性告警真问题准确率95%可行动收到告警知道该干什么分级合理紧急程度清晰不重要的不打扰人坏告警的特征频繁触发又自动恢复“抖动”阈值不合理要么不报要么狂报告警信息不清晰看完不知道是什么问题告警没收敛一台机器故障引发20条告警2.2 告警的四个层级【P0 - 紧急/立即响应】 • 业务核心功能不可用 • 影响范围所有用户 • 响应时间5分钟内 • 通知方式电话 短信 钉钉 【P1 - 高/30分钟内响应】 • 业务部分功能受损 • 影响范围部分用户或部分功能 • 响应时间30分钟内 • 通知方式钉钉 短信 【P2 - 中/工作时间处理】 • 非核心问题性能下降 • 影响范围少量用户 • 响应时间4小时内 • 通知方式钉钉群 【P3 - 低/记录观察】 • 优化建议潜在风险 • 响应时间下一个工作日 • 通知方式工单系统三、PromQL表达式从指标到告警规则3.1 核心PromQL函数# 速率类处理Counter类型 rate(http_requests_total[5m]) # 5分钟平均速率 irate(http_requests_total[1m]) # 1分钟瞬时速率 increase(http_requests_total[1h]) # 1小时增量 # 聚合类 sum(rate(http_requests_total[5m])) # 求和 sum by (service) (rate(http_requests_total[5m])) # 按维度分组 avg by (instance) (cpu_usage_percent) # 平均值 max by (cluster) (memory_usage_bytes) # 最大值 # 分位数 histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) histogram_quantile(0.95, sum by (le, service) (rate(http_request_duration_seconds_bucket[5m]))) # 预测 predict_linear(memory_usage_bytes[6h], 3600) # 6小时后预测值 # 异常检测 absent(up{joborder-service}) # 指标缺失 changes(process_start_time_seconds[1h]) # 进程重启3.2 关键告警表达式可用性告警# 1. 服务完全不可用 up{joborder-service} 0 # 2. 服务可用性低于99% sum(rate(http_requests_total{joborder-service, status~5..}[5m])) / sum(rate(http_requests_total{joborder-service}[5m])) 0.01 # 3. 实例心跳丢失5分钟无响应 time() - max by (instance) (timestamp(up{joborder-service})) 300性能告警# P99延迟超过1秒 histogram_quantile(0.99, sum by (le, service) (rate(http_request_duration_seconds_bucket[5m])) ) 1 # P95延迟超过500ms histogram_quantile(0.95, sum by (le, service) (rate(http_request_duration_seconds_bucket[5m])) ) 0.5资源告警# CPU使用率持续80% 100 - (avg by (instance) (rate(node_cpu_seconds_total{modeidle}[5m])) * 100) 80 # 磁盘空间不足小于20% 100 - ( (node_filesystem_avail_bytes{fstype!tmpfs} * 100) / node_filesystem_size_bytes{fstype!tmpfs} ) 80 # 内存使用率90% (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 90 # 文件描述符使用率80% (node_filefd_allocated / node_filefd_maximo) * 100 80四、告警规则的工程设计4.1 告警规则模板# /etc/prometheus/rules/order-service.ymlgroups:-name:order_service_alertsinterval:30s# 评估频率rules:# 规则1订单服务P99延迟告警-alert:OrderServiceP99LatencyHighexpr:|histogram_quantile(0.99, sum by (le, service) ( rate(http_request_duration_seconds_bucket{ serviceorder-service, uri!/health }[5m]) ) ) 1for:2m# 持续2分钟才触发避免抖动labels:severity:P1team:order-teamservice:order-servicecategory:performanceannotations:summary:订单服务P99延迟过高 ({{ $value | humanizeDuration }})description:订单服务P99延迟达到{{ $value | humanize }}超过1秒阈值# 关键告警要带行动指引runbook:https://wiki.example.com/runbook/order-service-high-latencydashboard:https://grafana.example.com/d/order-service?var-instance{{ $labels.instance }}impact:用户下单体验受损可能影响转化率action:|1. 查看Grafana仪表盘定位慢请求 2. 检查下游依赖库存、支付是否正常 3. 查看JVM GC情况 4. 如持续恶化考虑扩容或限流4.2 告警抑制Inhibit Rule核心思想上游告警触发时抑制下游告警避免告警风暴。# alertmanager.ymlinhibit_rules:# 整个集群宕机时抑制单个实例告警-source_match:alertname:ClusterDownseverity:P0target_match:severity:P1equal:[cluster]# 服务整体不可用时抑制性能告警-source_match:alertname:ServiceDownseverity:P0target_match:category:performanceequal:[service]# 数据库宕机时抑制所有依赖数据库的告警-source_match:alertname:DatabaseDowntarget_match:service:.*equal:[datacenter]4.3 告警分组Group# alertmanager.ymlroute:group_by:[alertname,service,cluster]group_wait:30s# 30秒内合并告警group_interval:5m# 5分钟后再发送新告警repeat_interval:4h# 同一告警4小时内不重复发送routes:# P0告警单独路由-match:severity:P0receiver:p0-pagergroup_wait:10srepeat_interval:5m# 数据库告警单独通知DBA-match:team:dbareceiver:dba-team# 默认路由-receiver:default-team五、告警降噪的五大实战技巧5.1 技巧一合理设置持续时间for子句问题瞬时抖动触发大量告警。解决根据业务特性设置合理的for时长。# ❌ 反例立即触发抖动敏感-alert:HighCPUexpr:cpu_usage80for:0s# 立即告警# ✅ 正确持续5分钟才告警-alert:HighCPUexpr:cpu_usage80for:5m# 过滤瞬时抖动# 不同指标的合理持续时间# 网络抖动for: 1m# CPU高for: 5m# 内存高for: 5m# 磁盘满for: 10m避免误报磁盘增长需要时间# 服务不可用for: 30s严格要求5.2 技巧二智能阈值动态阈值问题固定阈值无法应对业务波动如大促期间流量翻倍。解决使用动态阈值或同环比。# 同环比告警比昨天同一时刻恶化50% expr: | ( sum(rate(order_created_total[5m])) - sum(rate(order_created_total[5m] offset 1d)) ) / sum(rate(order_created_total[5m] offset 1d)) -0.5 # 动态阈值基于历史7天同时刻的P95 expr: | sum(rate(http_requests_total[5m])) quantile_over_time(0.95, sum(rate(http_requests_total[5m]))[7d:1h] ) * 1.55.3 技巧三业务时段区分问题业务低峰期的正常指标波动被误判。解决区分工作时间和非工作时间。# 不同时间段使用不同阈值-alert:HighErrorRate_BusinessHoursexpr:error_rate0.01for:2mactive_time:08:00-22:00# 仅工作时间告警-alert:HighErrorRate_NonBusinessHoursexpr:error_rate0.05for:10mactive_time:22:00-08:00# 非工作时间放宽阈值5.4 技巧四告警去重与合并问题同一问题触发多条类似告警。解决在AlertManager中配置合并规则。route:group_by:[alertname,service,instance]group_wait:1m# 1分钟内同组告警合并group_interval:10m# 10分钟后再发送同组新告警# 合并策略相同服务多条告警汇总为一条group_interval:5mroutes:-match_re:service:^(order|payment|inventory)-service$group_by:[service]# 按服务汇总receiver:team-aggregated告警消息聚合示例【订单服务异常告警】5条告警合并 1. [P1] OrderServiceP99LatencyHigh instance-01 P991.5s 2. [P1] OrderServiceP99LatencyHigh instance-02 P991.8s 3. [P2] OrderServiceHighCPU instance-01 CPU85% 4. [P2] OrderServiceHighCPU instance-02 CPU88% 5. [P2] OrderServiceSlowQueries count15 影响订单服务整体性能下降 Runbookhttps://wiki.example.com/runbook/order-service5.5 技巧五告警静默Silence与维护窗口问题计划内的维护操作发布、扩容也会触发告警。解决使用静默规则。# 维护窗口静默API方式amtool silence add \--alertmanager.urlhttp://alertmanager:9093 \--comment订单服务发布 \--duration30m \--start2026-07-20 14:00 \--matchserviceorder-service自动化方案# 发布时自动添加静默规则importrequestsdefadd_maintenance_silence(service,duration_minutes30):silence{matchers:[{name:service,value:service,isRegex:False}],startsAt:datetime.utcnow().isoformat()Z,endsAt:(datetime.utcnow()timedelta(minutesduration_minutes)).isoformat()Z,comment:f自动静默{service}发布维护,createdBy:deployment-system}requests.post(http://alertmanager:9093/api/v1/silences,jsonsilence)六、SLO驱动的告警设计6.1 SLI/SLO/SLA概念SLAService Level Agreement服务等级协议对外的承诺 ↓ 量化 SLOService Level Objective服务等级目标内部目标 ↓ 度量 SLIService Level Indicator服务等级指标量化指标示例SLA99.9%可用性对客户承诺SLO月度可用性99.95%P99延迟500msSLI可用性 成功请求数 / 总请求数延迟 histogram_quantile(0.99, …)6.2 错误预算Error Budget核心思想SLO不是越高越好要平衡可靠性和迭代速度。SLO 99.9%可用性 月度错误预算 (1 - 0.999) × 30 × 24 × 3600 259.2秒 当月已消耗错误预算 200秒 剩余预算 59.2秒 策略 - 预算充足正常迭代 - 预算紧张20%暂停非必要发布 - 预算耗尽停止所有新功能发布专注稳定性6.3 SLO告警规则# 基于错误预算的告警-alert:ErrorBudgetBurnRateexpr:|( sum(rate(http_requests_total{status~5..}[1h])) / sum(rate(http_requests_total[1h])) ) (1 - 0.999) * 14.4 # 1小时消耗月度预算的1/14.4for:5mlabels:severity:P1slo:availability-99.9%annotations:summary:错误预算燃烧速率过高description:过去1小时错误率{{ $value | humanizePercentage }}按此速率月度预算将提前耗尽action:考虑暂停非必要发布优先修复稳定性七、Recording Rule性能优化7.1 预计算常用指标问题复杂PromQL在Grafana中执行慢告警评估也慢。解决使用Recording Rule预计算。# /etc/prometheus/rules/recording.ymlgroups:-name:recording_rulesinterval:30srules:# 预计算订单服务QPS-record:order_service:request_rate:5mexpr:|sum by (service, status) ( rate(http_requests_total{serviceorder-service}[5m]) )# 预计算P99延迟-record:order_service:latency_p99:5mexpr:|histogram_quantile(0.99, sum by (le, service) ( rate(http_request_duration_seconds_bucket{serviceorder-service}[5m]) ) )# 预计算错误率-record:order_service:error_rate:5mexpr:|sum(rate(http_requests_total{serviceorder-service, status~5..}[5m])) / sum(rate(http_requests_total{serviceorder-service}[5m]))告警规则中使用预计算指标# 直接引用预计算结果告警评估更快-alert:OrderServiceHighErrorRateexpr:order_service:error_rate:5m0.01for:2m7.2 Recording Rule设计原则适合Recording Rule的场景多个告警规则/Dashboard重复使用的复杂查询高频评估的查询涉及大量时间序列的聚合不适合的场景简单的单指标查询一次性的临时查询八、AlertManager高级特性8.1 通知模板# alertmanager/templates/wechat.tmpl{{define wechat.default}}{{range .Alerts}} 告警通知 【告警级别】{{.Labels.severity}}【告警名称】{{.Labels.alertname}}【服务名称】{{.Labels.service}}【实例】{{.Labels.instance}}【触发时间】{{.StartsAt.Format 2006-01-02 15:04:05}}【告警描述】{{.Annotations.description}}【处理建议】{{.Annotations.action}}【Runbook】{{.Annotations.runbook}}【Grafana】{{.Annotations.dashboard}}{{end}}{{end}}8.2 多渠道通知# alertmanager.ymlreceivers:-name:p0-pagerwebhook_configs:-url:http://alert-webhook:8080/phone-call# 电话告警send_resolved:truewechat_configs:-corp_id:xxxagent_id:xxxapi_secret:xxxto_user:all-name:default-teamwechat_configs:-corp_id:xxxagent_id:xxxapi_secret:xxxto_user:order-team-name:dba-teampagerduty_configs:-service_key:xxx8.3 升级策略Escalation# 告警5分钟未确认电话通知主管escalation_configs:-match:severity:P0escalation:-to:oncall-engineerduration:0-to:team-leadduration:5m-to:directorduration:15m九、实战案例从3万条/月到300条/月9.1 第一阶段全面告警反例问题200条告警规则每月30000告警95%是噪音团队告警疲劳根因阈值不合理没有for子句没有分级没有抑制规则没有静默机制9.2 第二阶段精细化改造核心动作1. 告警规则优化200条→80条# ❌ 删每种HTTP状态码一个告警-alert:Http500Errorexpr:rate(http_requests_total{status500}[5m])10-alert:Http502Errorexpr:rate(http_requests_total{status502}[5m])10-alert:Http503Errorexpr:rate(http_requests_total{status503}[5m])10# ✅ 改5xx统一告警-alert:HttpServerErrorRateexpr:|sum(rate(http_requests_total{status~5..}[5m])) / sum(rate(http_requests_total[5m])) 0.01for:2m2. 加入抑制和分组inhibit_rules:-source_match:{alertname:ServiceDown}target_match:{category:performance}equal:[service]3. 引入SLO告警基于错误预算的告警替代了CPU/内存/磁盘等基础设施告警。4. 业务时段区分非工作时间降低告警敏感度。9.3 效果对比指标改造前改造后改善告警规则数20080-60%月告警数30000300-99%有效告警占比5%95%90%误报率95%10%-89%故障发现时间15min2min-87%告警响应率30%98%227%十、踩坑总结10.1 踩坑1阈值拍脑袋问题阈值没经过数据分析“先这样设置看看”。解决基于历史数据过去30天P95/P99设置阈值结合业务SLO目标动态调整而非一成不变10.2 踩坑2告警太多重要告警被淹没问题核心服务挂了但20条非关键告警先到。解决告警分级P0/P1/P2/P3P0单独通知渠道抑制非关键告警10.3 踩坑3告警没有行动指引问题收到告警不知道该干什么到处查文档。解决每条告警必须带Runbook链接标注影响范围和建议动作告警信息包含Dashboard和Trace链接10.4 踩坑4Prometheus单点问题Prometheus挂了整个监控体系崩溃。解决Prometheus双实例部署使用Thanos/Mimir实现长期存储和高可用关键告警使用多数据源Prometheus VictoriaMetrics10.5 踩坑5告警没回执问题告警发出后不知道是否有人处理。解决告警需要确认机制定期巡检告警处理情况未处理的告警自动升级通知十一、总结告警体系建设的核心是质量而非数量。关键要点告警即代码用YAML管理告警规则纳入Git版本控制SLO驱动基于错误预算告警避免无目标的指标监控持续时间for过滤瞬时抖动抑制与分组避免告警风暴分级处理P0/P1/P2/P3分渠道通知可行动每条告警带Runbook和Dashboard降噪是持续过程定期review告警删除无用规则告警设计的哲学如果你收到告警却无能为力或者收到太多告警以至于麻木那这个告警体系就是失败的。好的告警体系应该让团队睡个好觉不会被噪音打扰快速响应真故障分钟级发现持续改进通过告警发现系统性问题未来演进AI异常检测基于历史数据自动学习正常模式告警收敛将多个相关告警合并为根因告警可观测性平台统一Grafana统一指标日志链路ChatOps集成在告警群中直接处理故障今日思考你们团队现在的告警规则有多少条有效告警占比是多少欢迎分享你的告警降噪经验作者架构实战团队日期2026-07-20标签#Prometheus #监控 #告警 #SRE #SLO #降噪