☰
基于Prometheus和Grafana的MongoDB监控与告警系统搭建实践
2026/10/8 9:27:27 网站建设 项目流程

我先说下这套东西的来历吧。团队里MongoDB实例一多,日常排查慢查询、连接数暴涨、复制延迟这些问题,全靠登服务器敲命令,效率太低,告警更是全靠运气。后来我把Grafana、Prometheus和mongodb_exporter这套组合拉起来,做了一个MongoDB性能监控仪表板,从抓取指标、可视化到告警通知一条链全打通。这篇文章就记录一下我搭建的完整过程,包括踩过的坑、指标怎么解读、告警规则怎么写,给也要做同样事情的朋友一份可以直接抄的作业。

1. 项目拆解:为什么是Prometheus+Grafana这套组合

1.1 三个组件各自扮演什么角色

先理清这套监控栈里每个成员的分工,不然你装完东西也不知道谁在干什么。

Prometheus是整个监控系统的核心,负责从各种Exporter定时抓取指标数据,存进自带的时间序列数据库里,同时承担了告警规则计算的角色。Grafana是纯可视化前端,从Prometheus查询数据,渲染成图表和仪表板。mongodb_exporter则是中间那个“翻译官”,它把MongoDB内部的监控指标(serverStatus、replSetGetStatus等命令返回的数据)转换成Prometheus认识的指标格式,暴露在/metrics接口上。

打个比方:MongoDB是工厂里的机器,mongodb_exporter是给机器装传感器的人,Prometheus是巡检员定时抄表记录数据,Grafana就是总控室的大屏幕,把抄下来的数据画成曲线。这个链条里没有哪一环是可有可无的,少了Exporter数据进不来,少了Prometheus没人存数据算告警,少了Grafana数据就只能躺在数据库里没法看。

1.2 整体架构和数据流转链路

这套架构的实际部署数据流是这样的:

MongoDB服务端开启监控相关的内置能力(比如free monitoring的替代方案是暴露serverStatus);mongodb_exporter以独立进程方式运行,在配置里指定要连的MongoDB实例地址,通过MongoDB驱动调用serverStatus等命令获取数据,再转换为Prometheus指标格式,监听在固定端口(默认9216)的HTTP服务上;Prometheus通过scrape机制,按你配置的时间间隔(通常15秒或30秒)访问Exporter的/metrics接口,拉取一次指标快照,存入本地TSDB;Grafana通过数据源配置连上Prometheus,执行PromQL查询语句,把结果以时间线、数值、柱状图等不同形式渲染出来。

这个链路里最容易被忽略的是Prometheus的抓取间隔和存储时长。抓取间隔决定了两边:一是图表上每条曲线的最小时间分辨率——抓一次的数据范围是最低15秒或30秒;二是Prometheus存储的损耗量——间隔越短写入越多、磁盘占用越大。存储时长则在运维侧决定你要不要加长期存储方案,默认本地存储的保留时间通常设到15天左右,超过就删旧数据。

1.3 和手动命令、其他监控方案对比

很多团队在刚开始做MongoDB监控时,会先试mongostat和mongotop这类官方命令行工具。它们能看瞬时状态,但不能形成历史趋势,每次要看都得人肉登录,告警更是无从谈起。官方的MongoDB Atlas和Ops Manager自带监控面板,但只有企业版或云托管场景下能省心用,自建社区的就没有这个待遇。

相比之下,Prometheus+Grafana这套组合的价值在于:开源、免费、部署轻量,指标留存在本地,可以自由画图表、自由配告警,还可以一套监控栈同时管MongoDB、MySQL、Linux主机、Nginx这些基础设施,不用为每种数据库单独造一套监控系统。这也是我最终选择这套方案的根本原因——一次投入,所有组件都长在一个体系里。

2. 环境准备:从零开始搭监控栈

2.1 版本选型与连接方式

先确定自己要监控的MongoDB版本,这会影响Exporter的兼容性选择和暴露指标的字段差异。我这边环境里有4.2和5.0两个大版本混跑,选用了mongodb_exporter 0.40.x版本(当时较稳定的版本),Prometheus用的2.45.x版本,Grafana用的9.5.x版本。这套组合对4.x和5.x版本都是兼容的。

mongodb_exporter有两种连接方式:一种是直连单个mongod节点,把该节点的实例级指标暴露出来;另一种是连mongos(分片集群的入口),拿到整个分片集群的路由层视角。监控副本集的话,更合理的做法是把Exporter分别指向每一个mongod节点,Prometheus端用不同job去区分;注意exporter本身只是连接到其中一个节点做采集,它不会自动探测副本集里其它节点。

连接串上的认证方式也必须提前确认。如果MongoDB开启了账号认证,Exporter使用的账号需要尽量小而够用——我建议单独建一个只读账号,给它clusterMonitor和readAnyDatabase这两个权限。用root或dbOwner去连Exporter不是不行,但那等于把高权限账号明文写进配置文件里,安全上不划算。

2.2 MongoDB侧需要关注的几个前置点

在装Exporter之前,先想清楚自己到底要监控什么层的内容。

第一个是实例层:连接数、内存、操作延迟、锁、队列、网络流量,这些来自serverStatus的输出,Exporter默认就能拿到,不需要额外开启什么开关。

第二个是复制层:副本集的主从状态、复制延迟、oplog时间窗口,需要通过replSetGetStatus命令获取。Exporter在探测到连接的目标是副本集成员时,会自动尝试抓这部分数据,前提是MongoDB账号有clusterMonitor权限。

第三个是慢查询和操作层面:要监控单个查询的耗时分布、全量慢日志统计,光靠serverStatus不够,需要开启MongoDB的Profiler(数据库分析器),并将profiling级别设为1(只记录慢操作)。Exporter本身不直接读system.profile集合,你可以在Grafana旁边再接一个日志采集方案,或者在MongoDB侧把慢查询日志输出到独立日志文件再由Promtail等采集。

这些前置点不是说要全部做完才能跑起来,而是你得在安装Exporter之前心里有数:我先做到什么程度,哪些监控能力后面再加。否则等装完才发现自己想要的指标根本没采集到,又要回头改配置。

2.3 三个组件的安装方式

安装步骤我就不写那种从头编译源码的折腾路径了,直接说容器化和二进制两种最常用的方案。

容器化是最省事的。我用docker compose把Prometheus和Grafana编排在一起,mongodb_exporter对每个MongoDB实例跑一个容器,或者用systemd方式跑一个进程管多个实例也可以。一个最小的docker-compose定义里,Prometheus挂载prometheus.yml配置文件和data目录,Grafana挂载数据目录以确忘记密码后还有恢复手段。

二进制方式适合没有Docker环境的内网服务器。Prometheus和Grafana都可以直接下载官方tar包解压运行,mongodb_exporter的GitHub Release页也有编译好的二进制。我初期的测试环境就是全二进制跑的,因为那时候服务器上没装Docker,图省事直接扔到/opt/monitor目录就开用。

不管哪种方式,记得确认端口在防火墙里是放开的。Prometheus默认9090,Grafana默认3000,mongodb_exporter默认9216。我之前碰到过Grafana运行了但网页打不开的情况,排查半天发现就是服务器安全组没放行3000端口。

3. 核心配置:让数据真正流动起来

3.1 mongodb_exporter连接串与常见配置项

mongodb_exporter启动时核心要配的是MongoDB的URI。一个典型的连接串长这样:

export MONGODB_URI="mongodb://monitor:yourpassword@127.0.0.1:27017/admin?tls=true&authSource=admin" ./mongodb_exporter --mongodb.uri=$MONGODB_URI --mongodb.collstats-coll-whitelist=test.* --mongodb.indexstats-collections=test.* --web.listen-address=:9216

这里几个参数说明下:

  • mongodb.uri:连接串,用户名密码以及认证库(authSource)都要写完整。如果不开认证,直接写mongodb://127.0.0.1:27017即可。
  • mongodb.collstats-coll-whitelist:如果开了collstats采集,这里限定要采集哪些集合,用正则库名.*或库名.集合名都行。不加这个参数会默认采集全部集合的collStats,库一多、集合一多,Exporter的采集量和Prometheus里生成的指标基数可能会失控,这问题下面细说。
  • mongodb.indexstats-collections:限定索引统计的集合范围,同样是为了控制指标基数。
  • --collect-all:新版本Exporter(0.30以上)默认开启的collector列表已经比较全,不需要显式打开太多开关。但如果你要用到某些特定指标,比如oplog统计(replSetStatus里的详情),就要手工检查对应collector是否开启。

配置好之后先手动curl一下Exporter的地址,确认返回的是Prometheus文本格式的指标内容:

curl -s http://127.0.0.1:9216/metrics | head -20

能看到mongodb_up这个指标值等于1,就说明Exporter已经成功连上MongoDB并采集到数据了。

3.2 Prometheus抓取配置与采集频率

Prometheus这边要做的就是在prometheus.yml里加scrape_config。下面是一个支持多实例的配置写法:

scrape_configs: - job_name: 'mongodb-cluster01' scrape_interval: 30s static_configs: - targets: ['10.0.0.11:9216'] labels: cluster: mongo-prod-a role: primary-check - job_name: 'mongodb-cluster02' scrape_interval: 30s static_configs: - targets: ['10.0.0.12:9216'] labels: cluster: mongo-prod-b role: primary-check

为什么要单独给每个实例建一个job而不是共用同一个job?因为每个job的采集目标独立的instance标签可以区分,但你在Grafana里做变量下拉时,如果所有mongod节点都挂在一个job下、靠instance标签区分,遇到副本集节点切换IP、主从角色变化时,面板的维度会非常乱。我习惯用cluster标签区分环境,再加job_name区分具体实例,这样在面板上可以按cluster做聚合视图、按instance看单节点细节。

scrape_interval的选择上,30秒在绝大多数监控场景都够用。如果你要看秒级的毛刺,比如操作延迟在某几秒内剧烈抖动,那可以缩到15秒,但Prometheus对存储和查询的压力都会上升,Grafana图表的渲染也会变慢。没有特殊需求我不建议低于15秒。

改完配置后用promtool check config做一次校验,然后reload Prometheus配置(支持热加载,kill -HUP进程或调用/-/reload接口都行),不要直接重启服务。

3.3 Grafana数据源接入

Grafana界面上只要做一处配置:在Configuration下的Data Sources里新增Prometheus类型,URL填Prometheus的地址,因为Grafana和Prometheus一般是同机部署,直接用http://localhost:9090就行。

接入后可以先在Explore页面跑一条最简单的PromQL验证链路通没通:

mongodb_up{cluster="mongo-prod-a"}

如果返回的结果里包含1,说明Prometheus数据源本身没问题。这里有个非常容易踩的坑:Grafana和Prometheus之间的时区处理。

Grafana面板右上角的时区如果和Prometheus服务器不一致,查询时会自动带上本地时区的偏移,导致明明有数据的指标却显示最近一段时间为空。我建议把Grafana的时区固定为UTC或者与Prometheus服务器保持完全一致,尤其是在跨时区的服务器上做过监控面板的人,这种问题排查起来非常费劲。我在踩过一次坑之后,所有监控环境都强制把时区设成UTC。

3.4 从模板导入还是从零自建仪表板

这一步是很多人会纠结的地方。Grafana官网有现成的MongoDB监控模板,搜索关键词mongodb就能找到,比较多人用的是ID 2583(对应mongodb_exporter 0.20.x时代)和新版适配的ID 14910等模板。

但我的建议是:你可以导入模板做初期参考,但最终必须有能力从零自己建一套面板。原因很简单——模板是别人按他自己的业务场景和指标命名画出来的,你的Exporter版本、指标命名、连接串大小写、标签命名都可能和模板对不上,结果就是导入了模板但一堆图表显示No data。与其花时间适配模板,不如理解每个指标代表什么含义,按自己的架构从零拖面板。

如果确定要导入模板,注意看模板说明里要求的Exporter版本和需要启用的collector。旧模板用了新版本Exporter里已经不暴露的指标名,那排障起来是最痛苦的,因为你不知道是该升级Exporter还是该换模板。

4. 关键指标解读与面板设计

4.1 连接数类指标:最先报警的地方

连接数是最容易出问题的指标之一。MongoDB的连接数是进程级别的资源,每个连接会占用文件描述符和线程资源,连接数暴涨通常意味着应用端连接池配置错误或者出现了连接泄漏。

在mongodb_exporter的指标里会出现类似这样的名字:

mongodb_connections{state="active"} mongodb_connections{state="available"} mongodb_connections{state="current"}

不同版本的指标名称可能略有差异,但语义基本一致。current代表当前建立的总连接数,available代表还剩下多少可用连接,active代表正在执行操作的连接。

我面板上会对current画两条线:一条是实际值,一条是MongoDB配置的最大连接数阈值。这样一眼就能看出剩余余量还剩多少。实际操作里见过一个最典型的场景:应用服务发版后连接池从100调到500,但MongoDB这边ulimit的限制没调,某天流量高峰直接把连接拉满,所有新请求全部排队超时,监控面板上连接数曲线笔直拉平的同时,操作延迟曲线也同步起飞。

4.2 操作延迟和命令执行频率:QDPS和耗时的真相

MongoDB的serverStatus里对read、write、command三类操作分别统计了总次数和总耗时,Exporter会对应暴露成类似这样的指标:

mongodb_mongod_op_latencies_read_total mongodb_mongod_op_latencies_write_total mongodb_mongod_op_latencies_commands_total

注意这里存的是从进程启动到现在的累计值,所以正确用法是配合rate()函数看每秒增量:

rate(mongodb_mongod_op_latencies_read_total[2m])

这样你得到的是最近2分钟内每秒操作数(QPS类)。如果你想看每次操作的平均耗时,用总耗时增量除以总次数增量:

rate(mongodb_mongod_op_latencies_read_sum_total[2m]) / rate(mongodb_mongod_op_latencies_read_total[2m])

这个平均延迟在查询压力发上去后会显著上升。配合Grafana里Stat面板显示当前平均延迟、Time series面板看趋势,可以非常直观地判断是不是有慢查询。

但这里有个我要提醒的事:总耗时是MongoDB内部从命令开始到结束的时长统计,它不包含网络传输和应用端的序列化时间。也就是说,如果你发现应用侧接口很慢但MongoDB平均延迟不高,问题大概率不在数据库这边,而在中间件或应用代码,别被面板上好看的数字迷惑。

4.3 内存与页错误:判断是否内存吃紧

MongoDB的WiredTiger存储引擎对内存的利用非常激进。指标里会看到:

mongodb_mongod_memory_bytes{type="resident"} mongodb_mongod_memory_bytes{type="virtual"} mongodb_mongod_memory_bytes{type="mapped"}

resident代表常驻物理内存,virtual是虚拟内存映射,mapped在WiredTiger引擎下有意义但不直接等于内存占用。这些数字不要单独看,要配合操作系统的总内存和MongoDB的cache配置一起看。

真正值得关注的是页错误指标。WiredTiger在内存中维护一个缓存池,当请求的页面不在缓存里就得从磁盘读,产生页错误。页错误增加意味着缓存命中率下降,磁盘IO压力上升,通常就是数据量增长到超过内存缓存能力的前兆。

面板上我习惯放两张图:一张是内存分配柱状图(resident、virtual叠加),另一张是页错误的速率趋势线。如果页错误持续上升且伴随磁盘读写延迟抬升,那不光是监控问题了,你得考虑扩容内存或者优化数据模型,避免全表扫描把大量页填进缓存、挤掉热数据。

4.4 锁、队列和读写竞争:并发能力的核心信号

在写入密集型场景下,锁等待和队列深度是不可或缺的指标。虽然WiredTiger比MMAPv1的锁粒度细很多,但并发写同一个文档时依然会有锁等待。

对应的核心指标大致有:

mongodb_mongod_wiredtiger_transaction_hashed 等事务相关指标 mongodb_mongod_global_lock_current_queue mongodb_mongod_global_lock_active_clients

你在实际Exporter暴露的数据里不一定能找到完全一样命名的指标,不同版本命名差异挺大,但语义都是围绕队列长度和等待客户端数量。global_lock_current_queue会区分total和readers、writers,如果写队列长期大于0,说明已经有操作在排队等待锁。

这里给个判断标准:队列偶尔冒尖是正常的,如果长期不为0,并且伴随操作延迟同步上涨,这时候要检查是否有大批量更新或获取操作在争抢同一个集合甚至同一个文档。常见案例是定时任务在高峰期批量update同一个大集合里的数据行,以为只跑了几分钟,实际把整个库的写能力拖垮了。

4.5 复制集和oplog:主从健康的晴雨表

副本集场景下要监控的指标集中在复制延迟和oplog时间窗口。

复制延迟比较好理解,就是主节点写入后,从节点落后了多少秒。我可以直接监控主从之间的时间戳差距,更常见的做法是在Exporter有对应的replSet指标时直接读取。oplog时间窗口则代表从当前时刻到oplog最老记录之间还能容忍多长时间的数据积压,如果oplog窗口小于复制延迟,说明从节点恢复时可能赶不上。

实际操作中我见过两次复制延迟告警:

一次是主库上做了一个大表的历史数据清理,删除了几千万条文档,从节点在同步删除操作时消耗大量CPU,延迟一度冲到10分钟以上。这时排查要看oplog窗口还剩多少,如果够大就不用慌,等大操作跑完延迟自然会追上。

另一次是网络问题导致主从之间的TCP连接反复断开重连,从节点的同步线程不断重新建立连接,延迟一路飙高。这类问题在监控里最明显的特征是:复制延迟曲线呈锯齿状,一会冲高一会回落,排查的方向是网络稳定性和防火墙对长连接的空闲超时设置。

4.6 面板设计的实操心得

面板不是指标越多越好,而是要按角色组织。我的MongoDB监控文件夹里分成三层:

第一层是总览Dashboard,只放核心状态,图不用多,3到5张即可:每个实例的up状态、当前连接数对比阈值、读写QPS概括趋势、复制延迟、oplog窗口。这层是给值班人和我扫一眼用的。

第二层是详细Dashboard,把内存、锁、队列、操作延迟、页错误、磁盘IO等指标都拆开画,每个指标单独一行或者用groupRows分组,主要用于出问题时深挖定位。

第三层是告警状态面板,展示当前Fire的告警列表和最近历史,不是实时指标图而是从Prometheus告警列表读出来的状态。

拖面板时有个小技巧:Time series面板里对指标做limit和聚合,避免仪表板一次查询上万条序列把浏览器卡死。用模板变量把cluster、instance做成下拉选项,可以大幅提升面板复用性——同一个面板切换环境和实例看数据,不用复制一堆重复面板。

5. 告警规则:从看到问题到提前发现问题

5.1 常用告警表达式速查

监控面板是给人看的,告警才是真正兜底的东西。我在Prometheus里配了下面这些规则,每一条都附上触发条件和触发后的含义:

告警项PromQL表达式触发含义
实例离线mongodb_up == 0Exporter连不上MongoDB或MongoDB挂了
连接数过高mongodb_connections{state="current"} > 8000当前连接数超过阈值,应用端或连接池异常
复制延迟过高mongodb_replset_member_replication_lag_seconds > 30从节点同步进度明显落后(阈值按业务容忍度调)
操作延迟突增rate(mongodb_mongod_op_latencies_write_sum_total[2m]) / rate(mongodb_mongod_op_latencies_write_total[2m]) > 1写操作平均延迟超过1秒,需立即排查
连接可用数过低mongodb_connections{state="available"} < 200剩余连接余量不足,快接近瓶颈

这些规则里的数字阈值一定要根据自己的实例规格和业务基准调整,没有通用的最佳配置。我的习惯是先用面板观察两周正常时期的指标基线,再按正常值的2到3倍设置告警阈值,既不会因为偶发毛刺频繁报警,也不会等到出事故才收到通知。

5.2 告警配置与通知渠道

Prometheus的告警规则写在rule_files指向的yml文件里,格式是:

groups: - name: mongodb-alerts rules: - alert: MongoDBInstanceDown expr: mongodb_up == 0 for: 2m labels: severity: critical annotations: summary: "MongoDB实例不可用" description: "实例 {{ $labels.instance }} 已连续2分钟不可达"

for: 2m的意思是,条件持续2分钟才触发告警,这个参数非常关键。不加for的话,Exporter在重启、网络短暂抖动时会产生大量瞬时告警。

有了告警规则后,通知渠道一般用Alertmanager,它可以对接企业微信、钉钉、邮件、Slack。我用的比较简单:规则触发后Alertmanager调用Webhook,经过告警去重和分组后推送到钉钉群。告警消息里带上instance标签和summary,群里的同学能直接看到是哪个环境的哪个实例出了问题。

5.3 避免告警风暴的几个技巧

我配完告警后第一周就被自己的告警群轰炸过。总结下来,告警设计有几个原则必须遵守:

第一,所有规则都要加for持续条件。瞬时抖动不算故障,只有持续一段时间才值得通知人。

第二,对已知的维护操作要有排查窗口或静默机制。比如重启MongoDB进行升级时,Exporter会短暂断连,这时候提前在Alertmanager配一个静默规则,不然值班人员会在半夜收到一堆“实例不可用”的假告警。

第三,阈值不要拍脑袋定。没看基线就设一个数字,要么永远不触发等于没配,要么天天触发把所有人弄麻木。

第四,告警规则要可归因。每一条告警的description里写清楚下一步应该看什么、常见原因是什么,方便接警的人不慌不乱。这一步虽然费时间,但真正出大事时省下的沟通成本远超投入。

6. 常见问题与排查实录

6.1 mongodb_exporter启动失败

Exporter起不来是最常见的问题,症状是进程起来后端口没监听,或者curl /metrics一片空。多数原因就是连接串不对:

  • 用户名密码里含有特殊字符没有URL编码,比如@、#这些字符会让URI解析错乱。解决方式是使用URL编码后的密码,或者在连接串里用params方式避开特殊字符。
  • 认证库写错。MongoDB的用户是跟着认证库走的,用户建在admin库,你却写成authSource=test,认证就直接失败。
  • 网络不通。Exporter和MongoDB之间如果有防火墙只放行27017端口,但Exporter所在机器访问不了,进程启动后反复重试连接。

排查这类问题最快的方式是在Exporter启动时加上--log.level=debug,看日志里MongoDB驱动的错误信息。日志会直接告诉你认证失败还是连接超时。

6.2 指标抓取超时或页面刷新过慢

Prometheus拉取Exporter的/metrics时如果频繁超时,排查点通常集中在Exporter的采集范围过大上。我在3.1提过collstats和indexstats的white-list配置,如果没限制而MongoDB里又有几千个集合,Exporter每次采集要遍历所有集合跑collStats命令,耗时会非常久,甚至把MongoDB自身拖慢。

这里一定要理解一个权衡:collstats采集范围越小、Exporter效率越高、Prometheus里指标基数越小,但你能看到的集合级统计就越少。如果确实需要监控所有集合的存储和索引情况,建议单独起一套低频采集任务(比如每5分钟拉一次),和常规的30秒高频任务分开,而不要放在同一个Exporter里全量采集。

6.3 Grafana图表显示No data

Grafana有图但显示No data,大部分原因集中在三块:

第一是PromQL写错。指标名不存在或者被改名了,最常见的是新旧版本Exporter指标名不一致。这里推荐一个排查方法:在Grafana的Explore页面里输入指标名的前缀,比如mongodb_,按自动补全列表看看当前环境实际有哪些指标。不用死记文档上的指标名,以实际返回为准。

第二是面板变量没配对。如果你用模板变量做了cluster下拉,但实际数据里的标签值不叫cluster而是叫instance,那查询就会匹配不到数据。检查变量定义时的标签名要和query里的匹配项一致。

第三是时间范围问题。前面说了时区导致的偏移,还有一种是当前时间和Prometheus存储范围对不上——查询时间跨度超出了保留期限,以前的数据被清了,面板当然空了。

6.4 高基数问题和存储膨胀

这一个坑是很多刚上手Prometheus的人容易踩进去的。

如果在collect全部集合的collstats时,每个集合都会产生几十上百个时序序列,几百个集合就是上万条序列。这些序列里还带着namespace标签,namespace的取值又特别多。Prometheus对每个序列都会建立索引并不断追加写入,时间一长内存和磁盘占用都会膨胀,查询性能也会下降。

解决的思路不是事后删数据而是事前控制:

  • 在Exporter侧用白名单限制采集范围
  • 在Prometheus抓取配置里用metric_relabel_configs过滤掉不需要的高基数标签
  • 在Grafana查询里使用sum()和rate(),减少返回的序列数量
  • 定期检查Prometheus的TSDB状态和内存消耗,必要时扩容或调低抓取频率

高基数问题一旦爆发,Prometheus的内存占用会居高不下,最典型的表现是查询响应突然变得很慢,甚至直接OOM。这套组合跑起来之后,监控自身成为新的运维负担,处理这个问题也算日常巡检的一部分。

6.5 仪表板模板导入失败或图表不匹配

导入模板时看到很多图表No data,第一反应是去检查模板说明里写的Exporter版本,然后对照当前环境的指标名。因为Grafana模板里的每张图都写死了PromQL,很多模板还混用了旧版Exporter才有、新版本已经改名的字段。

不匹配时的选择有三条:一是按模板里的PromQL去Exporter的/metrics输出里搜索近似指标名,替换掉;二是放弃模板根据自己的指标名重画;三是升级或降级Exporter版本适配模板。一般来说我建议选第一种或第二种,因为Exporter版本应该按MongoDB版本选,而不是被一个第三方模板牵着走。

7. 最后再分享几个我留下的习惯

虽然主体流程都在上面写完了,但有几个小习惯我觉得很值得讲一讲,都来自实际踩坑教训。

第一个是监控面板和告警规则要纳入版本管理。Prometheus的rule文件、Grafana的Dashboard JSON、docker-compose文件这些,单独放在Git仓库里。每次改了阈值或加了一张图,提交一次。这样出了问题到处都是可审阅的历史,不会出现“上周谁偷偷把复制延迟阈值从30改到300了”这种无法追溯的混乱。

第二个是每季度做一次告警自检,把每条告警规则拿出来回顾一遍,看最近三个月它触发了几次、误报率多高、有没有哪条从没触发过。完全没触发过的规则大概率阈值设得太松,或者指标本身采集不到。给规则做“体检”比新加规则更有价值。

第三个是建立监控的监控。Prometheus自身不可用了怎么办?Exporter挂了但MongoDB还正常,运维怎么看得到?我的做法是用一条最简单的黑盒探活脚本,定时检查Prometheus的/-/healthy接口和关键Exporter的/metrics接口,探活失败就发邮件给主值班人。监控系统不是天然可靠的,它也需要自身有逃生通道。

这套方案从部署到现在稳定跑了不短时间,MongoDB的几次问题都是先由面板曲线给出信号、再由告警第二条线通知到位。要说最重要的心得,其实就一条:先理解每个指标的来源和含义,再往面板上堆图表,最后才是配告警做闭环。中途省掉任何一步,后面排障就会加倍补回来。希望这份实战记录能帮你少走我走过的弯路,把监控真正做成运维的千里眼而不是鸡肋装饰。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询