尧图精选

Grafana告警配置实战:从被动监控到主动告警的完整指南

🕒 发布时间:2026/10/2 8:55:34 📁 来源:尧图网络
凌晨三点监控大屏上其实早就一片血红了CPU、内存、错误率三条曲线跟心电图急停似的。但问题就出在“其实早就红了”这六个字上——大屏挂在办公室没人二十四小时盯着它报警电话反而是客户那边打过来的。从那次之后我做了一件事把Grafana从一块被动展示的屏幕改造成一个主动喊人的告警中枢。这篇文章不讲那些官方文档里已经写烂的基础概念而是从一个实际运维者的角度把Grafana配置页面告警这条链路上最容易卡住人的地方、最容易被忽略的细节、以及踩过坑之后总结出来的经验完完整整捋一遍。适合谁看呢两类人一是团队里监控面板已经搭起来了、但告警一直没正经配上的同学二是配了告警但总在“该响不响、不该响乱响”之间反复横跳的运维老手。无论你是刚接触Grafana的新手还是已经在用Prometheus、Loki、Alertmanager的进阶用户这篇文章里提到的思路和排错方法都能直接拿过去用。1. 监控图表不会喊救命——为什么非配告警不可1.1 一次凌晨故障让我彻底改变了监控习惯那次故障具体是什么业务我就不说了过程很有代表性凌晨两点数据库连接数开始缓慢上涨当时的监控面板上Connections曲线从200慢慢爬到1900距离限额还差一口饭。面板画得清清楚楚问题在于没人看。等我第二天早上刷手机看到客户群里有人问“昨晚是不是有问题”的时候祸已经闯完了。这件事让我彻底想明白一个道理监控系统和告警系统是两码事。监控解决的是“出了问题如何定性”告警解决的是“出了问题如何及时知道”。大多数人用Grafana就停留在第一层图表画得漂漂亮亮然后在运维群里挂个链接让大家“有事自己看”。可一旦没有人主动去看监控的价值就等于零。所以在Grafana上配告警不等于简简单单在某块面板上加个Alert标签栏它背后的逻辑是把“需要人关注的状态”翻译成“可以被程序判断的条件”再通过稳定的通知渠道推给正确的人。这一整条链路才算真正把监控用了起来。1.2 新版告警和旧版Dashboard Alert先分清楚你用的是哪一套配告警之前有个前提要搞清楚你现在用的是Grafana的哪套告警体系页面完全不同配置思路也完全不同。Legacy Dashboard Alert旧版面板告警在某个Panel的Alert标签里配置写查询条件、设置阈值、选评估周期最后把通知发到旧的联系人渠道。它的缺点是告警和面板强绑定面板删了告警也没了而且通知方式、去重、分组能力都很弱。Grafana官方早就把它标记为废弃功能9.0之后新装实例默认走的是新版告警。Unified Alerting新版统一告警从Grafana 8.0开始引入9.0之后全面接管。它把告警规则、联系人、通知策略三者解耦规则可以独立于面板存在支持多数据源支持非常细的路由匹配和分组聚合。绝大多数人现在打开Grafana左侧菜单里看到的是Alerting这个独立入口也就是新版。如果你在面板编辑里看到黄色的Alert标签那多半是还在用旧版。建议尽早迁移到新版因为新版不只是页面变了更重要的是它把告警从“展示附属品”提升到了“完整子系统”的位置。还有一个容易混淆的概念是Prometheus Alertmanager。很多人以为Grafana的告警功能就是Alertmanager两者确实有关系但不一样Alertmanager是Prometheus体系中负责接收由Prometheus服务器预计算好的告警事件然后做分组、抑制、静默并发送通知的组件而Grafana Unified Alerting自己有内置的Alertmanager实现同时也可以选择“使用外部Alertmanager实例”来接管通知发送。简单理解Grafana负责基于数据源查询条件计算告警Alertmanager负责把计算出来的告警怎么发、发给谁、什么时候发。新版Grafana里如果是默认配置这个“怎么发”的活就是Grafana自己那套联系人和通知策略在干。提示到底用Grafana自带Alertmanager还是对接外部的Prometheus Alertmanager取决于你的架构。如果Prometheus已经被你用得滚瓜烂熟、Alertmanager里的路由和抑制规则也都沉淀好了那就继续沿用外部方案如果只是单纯用了Grafana做可视化不想再维护一套Prometheus告警规则那直接使用Grafana原生告警是最省事的。2. 告警规则的三个底层要素查询、条件、评估2.1 告警查询和仪表盘查询的差异很多人配置告警的时候第一个动作是去仪表盘的Panel里复制查询语句直接粘到告警规则里面。这种做法在简单场景下能跑通但一旦条件复杂就会出现各种奇怪行为。为什么因为仪表盘查询和告警查询的运行环境完全不同。仪表盘查询重点关注“展示效果”它会根据你选的时间范围自动调整$__interval等变量用来适应不同跨度的图形展示。而告警规则的查询是在后台周期性执行的评估任务它不关心你在页面上选了多长的时间范围只关心Evaluate every这个评估周期以及你在查询里写死或者动态计算的时间窗口。我见过最典型的问题有人把仪表盘里的rate(requests_total[5m])原封不动搬到告警规则里配置的评估周期是1分钟看起来没问题。但实际上[5m]这个范围在仪表盘里会被$__interval替代成几秒或几十秒的粒度在告警评估时却用的是固定5分钟两者得到的瞬时速率形态完全不一样阈值自然也不一样。所以在写告警查询的时候建议遵守几条原则尽量显式指定时间窗口比如rate(http_requests_total[5m])不要依赖$__interval。确保查询返回的是一个数值Prometheus数据源返回单个时间序列是可以的但如果你想让它变成一个标量条件需要配合Reduce、Threshold等表达式。先到Explore页面里手动执行一遍查询看返回的值是什么样的量级再定阈值。这条建议价值连城能省掉后面无数个“为什么没触发”的深夜。2.2 For参数与评估周期怎么选告警规则里主要有两个时间相关参数Evaluate every评估周期和For持续判定时间。这两个参数是新手最容易踩坑的地方也是告警规则精度和误报之间的平衡杠杆。Evaluate every表示每隔多久评估一次这条规则。比如填1m就是每分钟跑一次查询检查当前值有没有满足触发条件。这个周期不是越短越好——评估本身需要去数据源拉数据如果数据源是Prometheus频繁查询会带来额外压力而且监控数据本身有采集间隔你搞一个5秒的评估周期很可能数据还没更新就被评估了白白增加误报概率。常规做法是评估周期和数据抓取周期保持同一量级比如Prometheus默认抓取间隔15s评估周期设置为1m到5m就非常合理。For参数的含义是条件满足之后必须持续满足多长时间才算真正触发。举个例子For: 5m意味着查询结果连续5分钟都超过阈值告警状态才会从Pending变成Firing。这个参数存在的意义是过滤掉瞬时毛刺。生产环境里CPU使用率瞬间飙升到95%很可能是定时任务、服务启动、批量导入造成的过了几秒就掉下来。如果没有For参数这种毛刺就会被当成故障推送到你手机上。我的经验是对CPU、内存这种波动敏感的指标For设置在5~10分钟比较安全避免毛刺告警。对磁盘空间饱和、证书即将过期这种只要满足就必然出问题的指标For可以设短甚至设为0尽快触发。评估周期和For要搭配着看评估周期1m、For 5m意味着至少需要5次评估持续命中才触发如果评估周期5m、For 5m那触发最快要10分钟因为第一次评估计算出条件满足后还要再等下一轮确认。2.3 容易翻车的“多序列”告警一个非常容易被忽略的细节你的查询到底返回了多少条时间序列如果查询条件里带了instance、host、pod这类基数较高的标签而且没有做聚合那么每个标签组合都会各自生成一个独立的序列Grafana会对每一个序列分别判断条件和触发告警。举例来说你有10台机器告警查询写的是100 - (avg(rate(node_cpu_seconds_total{modeidle}[5m])) * 100) 90并且没有加instance过滤那么这个查询会返回10条序列每条对应一台机器的CPU使用率。如果其中3台超过90就会生成3条独立的告警事件。这个行为本身合理但容易让没有思想准备的人懵住——“怎么一下子来了一堆告警”如果你想得到的是一个整体聚合结果那就必须显式聚合比如max()、sum()、avg()。如果你就是想要每台机器独立告警那也没问题但要清楚知道这条规则在机器数量增多时会变成多少量的告警。另外还有一个细节如果查询返回了多序列后续接入通知策略时每条告警都带有各自的标签比如instancenode01这些标签可以作为路由匹配的依据也能在通知消息里展示具体是哪台机器出了问题。3. 操作链路从新建规则到通知触达的完整配置3.1 新建告警规则页面上的每个字段怎么填现在进入正题一步步看Grafana的告警配置页面。菜单路径是Alerting - Alert rules - New alert rule打开后有三个步骤区域但也有不少进阶字段隐藏在折叠区域里。我把关键字段逐一拆开讲。Rule name规则名称建议包含明确的指标和对象例如“生产环境-API网关-5xx错误率超5%”而不是“Test1”这种。告警通知里默认会带上规则名取一个能直接看懂的名字等于省去后续翻上下文的时间。Folder文件夹规则必须存放在某个文件夹里。这个文件夹和面板共用一套文件夹体系建议先建好几个业务用途清晰的文件夹比如“核心服务告警”“基础设施告警”避免所有规则堆在一个地方日后维护会疯掉。Group评估组Grafana把告警规则按组来调度评估。同一个组里的规则使用统一的评估间隔在New evaluation group下拉框里可以设置优点是评估任务可以被批量调度节省资源。我的建议是评估周期相同的规则放在同一个组。如果你把所有规则都塞进默认组但其中一条要改成10秒评估一次你会发现这个设置是全局的导致所有规则都被带过去很尴尬。Queries and expressions查询与表达式这是规则的数据来源。选好数据源填查询语句。如果阈值判断需要二次计算可以在数据源节点后面添加表达式节点常用的是Reduce把一段时间的多个点聚合成一个值可选last、mean、max等告警阈值判断通常用这个。Threshold在Reduce之后加一个阈值判断输出0或1来控制条件。这个在新版里更多是作为条件节点使用。Math做一些简单的加减乘除组合计算。举个实际配置要监控某个服务的请求成功率低于95%查询可以用sum(rate(http_requests_total{jobapi-gateway, status~2..}[5m])) / sum(rate(http_requests_total{jobapi-gateway}[5m]))然后紧跟着一个Reduce选last再跟一个Threshold设置IS BELOW 0.95。注意这里由于做了除法返回的值就是0到1的小数阈值别填成95很多新手在这里翻车。Pending period等待期就是前面说的For参数在规则列表里也能看到。3.2 配置联系人流程Contact Point告警规则计算出来之后下一步是通知到人。菜单入口是Alerting - Contact points。每个Contact Point代表一种通知方式常见的有Email、Slack、PagerDuty、Webhook、钉钉等。以邮件为例第一次配置的时候最容易漏掉的是SMTP。Grafana默认不会发送邮件必须在配置文件的[smtp]段里填好SMTP服务器信息[smtp] enabled true host smtp.example.com:465 user alertexample.com password your-password from_address alertexample.com from_name Grafana Alert修改配置文件后需要重启Grafana服务。这个步骤很多人卡住点了测试邮件一直报“SMTP not configured”问题就在这里。Webhook是一种万能通知方式尤其适合对接企业内部系统。创建Contact Point时选择Webhook填写回调URL。默认的payload是Grafana定义的JSON结构里面包含告警标题、描述、标签、状态、时间等字段。如果你的内部系统只需要收到“标题和摘要”可以不改默认的JSON结构直接接。如果对接的是钉钉、企业微信这类封闭消息平台往往需要配置自定义模板把Grafana的JSON转换成对方要求的格式这个后面讲进阶的时候详细说。创建好Contact Point之后别忘了一个动作点右边的Test按钮确认这个消息能够正常发出去。测试是分两步验证先验证集成本身工作再验证路由是否把规则投递到这里。3.3 通知策略告警消息最终由谁接收光有Contact Point还不够还要让告警规则知道“去哪发”。这个对应关系就是Alerting - Notification policies。通知策略本质是一个树状结构最顶层是默认策略Default policy下面的子策略通过标签匹配来筛选告警。每个策略决定一组告警如何分组、发送到哪个Contact Point。可以这样理解Contact Point是信箱Notification Policy是分拣员。告警出来之后是一个个带着标签如severitycritical、serviceapi的“包裹”分拣员根据包裹上的标签决定投递到哪个信箱。举个例子我想让critical级别的告警走Webhookwarning级别的告警走邮件可以这样设计默认策略匹配所有告警投递到邮箱联系人分组按grafana_folder字段。子策略A匹配severitycritical投递到Webhook联系人。子策略B匹配severitywarning投递到邮件联系人。配置子策略时注意匹配规则是标签键值对的完全匹配比如要匹配多个标签值可以用正则表达式但不能写两个相同的标签键。这里有一个超高频坑很多人创建了子策略之后原本规则的标签没配对导致告警还是按默认策略走结果该发Webhook的发到邮箱里去了。所以配置完策略建议先在Alerting - Alert rules里查看某条规则的“Notifications”标签列它会告诉你这条规则实际被路由到了哪个策略。4. 告警不触发、不通知排查思路比答案更重要4.1 规则状态正常却一直Pending告警规则列表里有状态列状态可以大致看到Normal、Pending、Firing、NoData、Error等。这里有个坑很多人看到状态是Pending而且持续很久就开始乱了以为是规则坏了。其实Pending恰恰说明条件已经满足了正在等待For时间期满。如果For设了30m那在过去30分钟内它一直Pending是完全正常的。等时间一过应该自动变成Firing。如果Pending了很久始终不变Firing按照下面几步排查点开规则详情查看最近一次评估的结果Grafana会把每轮评估生成的具体值列出来。对照一下当前阈值看看值是不是真的稳定超过了。确认For参数有没有写错。很多人把For填了30m却忘了这会导致触发延迟半小时以为是Bug。在Explore里手动执行同样的查询看当前最新值是什么。需要注意的是告警评估用的是“最后一条样本窗口计算”如果数据源最近几分钟没有新样本写入抓取断了评估依然在继续但值已经失真。如果状态是NoData意思是查询结果为空。造成这个的可能有很多比如标签写错、时间窗口太短导致窗口内没有数据、数据源被停了。NoData本身也可以被配置成触发告警在规则里把条件选成“NoData”即可很多时候服务静默挂掉比尖峰更可怕我建议核心服务都加一条NoData告警。4.2 测试通知成功但真实告警不推送这是群里被问烂了的问题Contact Point点Test能收到结果真实告警触发后一条消息都没有。这个问题的核心在于——Test按钮只测试了Contact Point本身的连通性它不测试进入这条告警的路由策略匹配而当一条真实告警进入通知策略树时有可能被其他策略截胡了。对应排查动作进入Alerting - Notification policies查看告警规则对应标签在当前策略树中会被谁匹配。把树当成一个路由表从上往下逐层核对。确认策略里选择的Contact Point和实际测试的是同一个。很多人开了两个邮箱联系人测试的是A路由指向的是BB恰好SMTP密码过期了。检查路由策略里的Group by字段是否造成了“等待合并而没立即发送”的错觉。如果Group wait设了30m那么一批新告警会在组里等待30m才发出第一条消息期间画面看起来就是“没通知”。4.3 重复通知和静默的坑告警触发之后如果一直没恢复通知会按照策略里的Repeat interval重复发送。默认值可能是4h或更久这应该符合大部分场景。但有人会把Repeat interval调成5m然后被自己配置刷屏这不算Bug。另外维护期间往往需要临时屏蔽告警用的是Alerting - Silences。静默的本质是标签匹配创建一条Silence填开始/结束时间。填入要匹配的标签比如instancenode01那么所有带这个标签的告警在指定时间内都不会发出通知。注意如果告警的标签里没有你想匹配的那个键值或者值不同静默就不会生效。标签匹配要求完全一致不是模糊匹配。所以我的建议是创建告警规则的时候从一开始就给规则加上规范的标签比如teamplatform、serviceapi、severitycritical。标签不仅仅用于路由还用于静默和后续的聚合分析这是很多教程没提的事。5. 让告警不泛滥又不漏报分组、抑制和告警疲劳5.1 分组参数到底怎么调不失控Grafana通知策略里有一组和分组相关的时间参数分别是Group wait、Group interval、Repeat interval。这三个参数看起来不起眼实际调优能把体验从“半夜被一百条短信炸醒”变成“一觉醒来清爽地看一条聚合消息”。Group wait一个分组首次产生第一条告警后等待多长时间才发送第一条通知。设短一点比如30s可以让同时发生的多条告警先归拢避免每次只来一条。Group interval在一组告警已经发过通知之后如果该组又产生了一条新的告警必须等待多长时间后才再次发送通知。它控制的是“组里新消息”的发送节奏。Repeat interval对于已经发送过的同一组告警如果它们还没恢复多久重复发送一次。举个例子网关服务挂了依赖它的5个微服务同时报“连接失败”这会产生5条不同规则的告警。如果Group by字段里包含service或者直接用默认的grafana_folder这5条告警可能被分到不同的组里分别发5次通知。如果把Group by设置成severity则它们有可能被合到同一个组Group wait30s、Group interval5m最后变成一条包含多条告警明细的消息发过来。这样体验就好多了。具体怎么调我的经验是Group wait默认30s~1m即可太长了告警延后严重。Group interval 5m比较合适既能及时通知新告警又不会每几秒就刷一条。Repeat interval按业务告警的重要性来critical可以是10m~30mwarning可以是2h~4h低优的可以24h都没问题。5.2 避免告警风暴的三个小手段告警风暴是监控系统里最破坏信任感的事。喊狼来了喊多了真出事反而没人看了。要避免这个问题除了前面说的分组和聚合还有几个手段值得试一试。手段一规则里用聚合查询而不是每台实例独立告警。比如监控Redis集群健康状态不要针对每台Redis实例单独告警而是用min()、avg()把集群整体状况拉出来。整体好但单节点有问题时靠单实例告警整体掉入危险线靠集群告警。分两级而不是一刀切。手段二把维护窗口提前纳入静默计划。常见的比如每周日凌晨的备份任务、每月的账单结算任务会天然导致指标波动。提前在Silences里创建好定时掩码也可以在Mute timings里配置每天/每周的静默时段比出了告警再去手动静默靠谱得多。手段三对上游和下游告警去重。大多数系统挂了会导致一连串“依赖方报错”比如数据库挂了所有连接池都会告警。这种场景下可以考虑为数据库服务单独建一个告警规则但是在依赖方侧保持告警规则只做记录不做通知可以设置静默策略或者路由到不通知的联系人这样只会收到根因的告警避免一堆衍生告警同时轰炸。5.3 一旦遇到“告警疲劳”先回头审视规则本身最后说点比较“软”的体会。配置告警这事最难的从来不是操作流程而是定力。如果你想给每一个指标都配上告警最后的结果一定是没人看通知。我给自己定的一个原则告警规则必须在“影响用户之前”或“需要人在一定时限内介入”的事件上有意义。比如磁盘使用率告警设在85%是为了让运维有时间清理而不是等到100%才通知接口错误率告警设在1%是为了能赶在这波流量爆掉之前介入。凡是那种“看起来指标很关键但实际上发生之后不需要人做什么动作”的情况就不该设成告警它可以进面板、进报表但不要进告警通知。那么在实际配置时我会建议你用这样的方式去检查已有的告警规则列出所有告警规则对每一条问一个问题这条告警触发之后值班的人需要采取什么行动如果答案是“不知道”那这条规则要么该删掉要么说明你根本还没想清楚指标和故障的关联。检查每条规则的通知策略。如果所有规则都走默认策略等于所有的告警都堆在一起这时候就算Grafana提供了再好的分组能力也救不回来。定期去Alerting - Alert rules看每一条规则的“Health”列。如果经常出现Error或NoData说明查询本身可能就存在问题先修规则再谈优化。配置Grafana告警本质上是一件需要持续迭代的事不是配完就一劳永逸。我现在的习惯是每季度重新看一遍整个Alerting结构把已经不再重要的规则删掉把新业务的核心指标补上再根据过去几个月的告警记录调整阈值和路由策略。每一次调整其实都在回答同一个问题在这个系统下一次出问题之前我们能不能更早知道一点更准确地知道一点。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →