EMQX监控实战:使用Prometheus和Grafana实现集群监控与告警 1. 为什么监控 EMQX 首选 Prometheus 和 Grafana1.1 EMQX 集群监控的三个层缺一不可做物联网平台的人应该都有同感EMQX 一跑起来日常运维的压力基本就全落在“连接数、消息吞吐、堆积”这几件事上。连接一多节点一扩容单靠 EMQX 自带的 Dashboard 点点看看已经不够用了。原因很简单Dashboard 看的是“当下”而监控要的是“连续的趋势”和“历史问题的回放”。我的理解里EMQX 的监控至少要覆盖三层系统层CPU、内存、磁盘、文件描述符、节点间的网络延迟。进程层Erlang VM 的运行状态、进程数、调度器利用率。业务层连接数、订阅数、消息发布速率、消息投递速率、消息堆积量、认证失败次数。系统层用 node_exporter 和 Prometheus 就能搞定进程层和业务层恰恰是 EMQX 自己能给出的指标最有价值。EMQX 5.x 内置了 Prometheus 协议的导出端点4.x 也有官方插件绕开了以前那种“自己写代码去解析 Erlang VM 内部数据”的方案。1.2 为什么不是自带的 Dashboard也不是 Zabbix / InfluxDBEMQX Dashboard 是给单机调试用的。节点一多你要横着对比多个节点的指标它做起来很别扭要看三天前凌晨发生了什么事它也没有这个能力。Zabbix 在传统 IT 监控里很强但采集指标要走 agent配置一次就得花不少心思。InfluxDB 适合时序写入但前端可视化你还得再搭一套。Prometheus 是主动拉取指标加上服务发现外加 Grafana 做展示这套组合成了云原生时代的默认答案。我之所以在一众方案里反复推荐 Prometheus Grafana还有一个很现实的原因社区里已经有人把 EMQX 的核心指标面板做好了导入即用。这就是生态的价值你不必从零开始画每一个图表。但光“导入即用”还不够你得理解面板背后的指标含义否则出了故障你想临时写一句 PromQL 都不知道从哪个字段下手。1.3 动手之前先搞清楚 EMQX 版本差异EMQX 4.x 和 5.x 的监控接入方式差别很明显。早期版本需要一个独立的 prometheus 插件在插件配置文件里设置认证 Token 和监听端口5.x 版本直接在核心里内置了对 Prometheus 协议的支持配置项更简洁指标也更规范。如果你还在维护老项目建议在动手之前先看一眼版本。4.x 的插件方案虽然也能用但 4.x 已经到了生命周期末期新需求尽量往 5.x 上靠。这篇文章里的实操部分会同时覆盖两个版本我自己生产环境用的是 5.x所以 5.x 的相关细节会更具体一些。2. 从 EMQX 侧把指标暴露出来2.1 5.x 内置 Prometheus 端点的配置方式EMQX 5.x 的 Prometheus 抓取端点默认不是开启的需要你在配置里显式开启监听器。最简单的办法是改etc/emqx.conf也可以直接在 Dashboard 的“配置”页面里搜prometheus关键字改我习惯直接改配置文件反正都一样。我测试环境里最小配置是这样dashboard { listeners.prometheus { bind 8083 authentication.enabled true authentication.api_key your_secret_token } }这个配置的意思是在 8083 端口上开一个供 Prometheus 抓取指标用的 HTTP 服务请求时要在 Header 里带Authorization: Bearer your_secret_token。如果只是内网测试不想搞认证可以把authentication.enabled设成false。但只要是能通外网的环境我强烈建议留着认证否则等于把内部运行状态裸奔在公网上。改完配置之后重启 EMQX或者在 Dashboard 里热加载配置。然后直接用 curl 验证端点是否通了curl -s http://127.0.0.1:8083/api/v5/prometheus/stats \ -H Authorization: Bearer your_secret_token | head -n 30返回内容就是以emqx_开头的一系列指标像emqx_connections_count、emqx_messages_received_total等等。看到这些说明端点没问题。2.2 4.x 老版本插件方案如果是 EMQX 4.x需要先安装插件。4.x 的插件一般在安装包里已经带了但默认禁用。你要在 Dashboard 的“插件”页面里找到emqx_prometheus把它启动起来然后修改插件配置vi /etc/emqx/plugins/emqx_prometheus.conf主要改两处一个是监听的port另一个是api_keyprometheus { port 8074 api_key your_secret_token }改完重启插件。4.x 的抓取路径和 5.x 不一样通常是/api/v4/emqx_prometheus服务端返回的指标同样以emqx_开头。如果你做的是一次从 4.x 往 5.x 迁移的监控改造转换成本其实很小主要就是改一下 Prometheus 里的 target 路径和认证头。2.3 指标端点验证的实操要点验证端点时不要只看“能不能访问”还要看“指标对不对”。我遇到过一种情况端口通、返回 200但指标里没有业务数据原因往往是请求到的是空指标集而真正的数据在另一个路径下。5.x 里常见的有几个路径/api/v5/prometheus/stats返回常规统计指标/api/v5/prometheus/message_metrics返回消息相关指标/api/v5/prometheus/erlang_vm返回 Erlang VM 相关指标。实际上你配监听器之后用/api/v5/prometheus/stats通常就够用了因为这条路径已经把大部分业务指标都带出来了。但为了保险起见最好在 curl 里加一个-g并且多试几个路径确认返回的指标数量不是零。提示EMQX 的 Prometheus 端点用的是 Bearer Token 认证。千万不要把 Token 写在 Prometheus 的scrape_configs明文里后随手传到 Git 仓库建议用环境变量引用或文件替换的方式管理。3. 部署 Prometheus把采集任务跑起来3.1 单机二进制部署五分钟搞定Prometheus 本体不挑资源最简部署直接下载二进制包就能跑。官网下不到的话可以找国内镜像或者 GitHub Releases 的代理下载。解压之后里面就是一个可执行文件加一个prometheus.yml配置文件就能启动。wget https://github.com/prometheus/prometheus/releases/download/v2.53.0/prometheus-2.53.0.linux-amd64.tar.gz tar xzf prometheus-2.53.0.linux-amd64.tar.gz cd prometheus-2.53.0.linux-amd64 ./prometheus --config.fileprometheus.yml默认监听 9090 端口浏览器打开http://localhost:9090就能看到 Prometheus 自带的简易查询页面。我习惯用 systemd 管理不前台运行方便开机自启。要是会用 Docker也可以直接用官方镜像但生产环境里二进制方式做进程管理更朴素也更稳。3.2 写一个能用的采集配置这里直接给一份我常用的配置模板目标场景是三个节点的 EMQX 集群global: scrape_interval: 30s evaluation_interval: 30s scrape_configs: - job_name: emqx metrics_path: /api/v5/prometheus/stats scheme: http static_configs: - targets: - 10.0.0.11:8083 - 10.0.0.12:8083 - 10.0.0.13:8083 labels: cluster: emqx-prod authorization: type: Bearer credentials_file: /etc/prometheus/emqx_token.txtscrape_interval我设了 30 秒不建议低于 15 秒。EMQX 的指标端点每次返回的数据量并不小拉太频繁反而增加节点负担对告警时效来说 30 秒已经足够。authorization这段是 Prometheus 2.x 之后的写法它会在抓取请求里自动拼上Authorization: Bearer credentials。credentials_file指向一个只包含 Token 文本的文件比直接写在 yml 里安全一点。如果是 4.x 插件把metrics_path改成/api/v4/emqx_prometheus就行。配置文件写好之后用promtool做一次校验./promtool check config prometheus.yml启动 Prometheus 后进入 Status 页面。如果 Targets 里显示 UP说明 EMQX 接入成功。如果显示 DOWN接下来看第四部分的排查表。3.3 采集频率和控制面开销的平衡接入 Prometheus 后EMQX 的 Dashboard 依然可以正常使用两者不冲突。Prometheus 拉取的是实时快照Dashboard 查的是内部状态没必要关掉任何一方。关于采集频率我再多说几句。有朋友把scrape_interval设成 5 秒理由是“要看到更细的曲线”。实际上 5 秒和 30 秒在 Grafana 上肉眼几乎看不出差别但 EMQX 节点的 CPU 会因为频繁序列化指标而上升几个百分点。对于以分钟为单位的业务响应15 到 30 秒是性能和精度的平衡点。4. Grafana 接入与监控看板配置4.1 Grafana 安装与数据源配置Grafana 的安装有很多种方式。我用的比较多的是 apt 源和 Docker跑在独立的小机器上。之前身边有人直接把 Grafana 装到 EMQX 节点上图方便但监控工具和业务服务混跑一旦监控组件出问题反过来影响业务不值得。还是单独一台虚拟机或者和 Prometheus 装在一起就好。装好 Grafana 后浏览器访问 3000 端口默认账号密码都是 admin。第一次登录会让你改密码顺手就把时区、默认首页调好习惯用中文界面的可以改语言选项。然后添加数据源左侧菜单进入 Configuration - Data Sources。选择 Prometheus。URL 填 Prometheus 所在地址比如http://localhost:9090。如果是远程的填完地址点最底部的 Save Test会提示 Data source is working。注意Prometheus 和 Grafana 之间没有做认证是常态内网环境这样够了。Grafana 本身的管理后台密码要改掉千万不要用 admin/admin 挂公网。4.2 社区模板导入与自适应调整EMQX 相关的 Grafana Dashboard 模板在 Grafana 官网可以搜到常用的模板 ID 有13383和17248这类社区模板还有官方仓库的 emqx dashboard 模板。导入方式很简单左侧 Dashboards - Import填入模板 ID然后选择你的 Prometheus 数据源。导入完成后你会看到一堆面板连接数趋势、消息发布速率、订阅数、集群节点状态、Erlang VM 资源占用等。模板虽好但注意两点模板里的 PromQL 字段名是基于某个 EMQX 版本的如果你的 EMQX 版本和模板作者不一致个别面板会没数据。模板通常假设你的数据源名字叫Prometheus如果你自定义了数据源名导入时要手动匹配。遇到空面板第一步永远是去 Explore 页面手敲一句 PromQL 确认字段到底是什么。不要急着改模板先把命名差异弄清楚。4.3 手写几张高频监控面板的 PromQL导入模板是第一步真正体现运维水平的是你会不会自己写查询比如这几个高频面板当前在线连接数sum(emqx_connections_count)消息流入速率sum(rate(emqx_messages_received_total[1m]))消息流出速率sum(rate(emqx_messages_delivered_total[1m]))消息堆积量sum(emqx_messages_queued_current)认证失败速率sum(rate(emqx_authentication_failure_total[1m]))各节点连接数排行topk(10, emqx_connections_count{clusteremqx-prod})这些指标在 EMQX 5.x 里基本都叫这个名字4.x 也差不多只是个别可能带emqx_前缀之外的后缀不同。写 PromQL 的时候先点开指标浏览器让 Grafana 自动补全字段名比硬背要高效得多。面板布局上我的习惯是把“连接数、消息速率、堆积”放在第一排“节点状态、Erlang VM 资源”放在第二排下面再放“认证失败、订阅变化趋势”。告警规则不要单独写在 Grafana 里否则每次调整阈值都要跑去编辑面板维护成本高。比较推荐的做法是 Grafana 里只负责展示Prometheus 的 rule 文件统一管理告警规则。5. 实操中踩过的坑与排查速查表5.1 三个典型坑每一个我都花过时间第一个坑是 Token 认证失败。Prometheus 配置了authorization但 EMQX 端返回 401。原因通常是换行符或者空格被一并写进了credentials_file。用echo -n your_secret_token /etc/prometheus/emqx_token.txt生成文件避免echo默认带换行。排查的时候一条curl -v看响应码就明白了。第二个坑是 4.x 插件路径记错。插件的默认监听端口和 prometheus 端点路径在不同版本里并不一致。我在帮朋友迁移的时候一直以为路径是/metrics结果拉取一直是 404。翻文档发现是/api/v4/emqx_prometheus。这个教训告诉我涉及跨大版本的事情第一件事永远是查对应版本文档不要凭经验猜。第三个坑是 Grafana 面板模板带入了历史数据偏差。模板导入后有个面板显示连接数几千但实际只有几百。后来发现是模板里加了[1d]的聚合导致平均值被拉高。改成max_over_time(emqx_connections_count[1m])这种靠近实时的聚合方式数据才正常。5.2 无伤大雅的常见问题速查表现象可能原因排查命令 / 步骤Prometheus Targets 显示 DOWN网络不通或端口错误用 curl 直接访问指标端点确认连通抓取返回 401Token 配置错误或 credentials_file 带换行用echo -n重写文件curl 加-v看认证头返回 404路径写错或版本不符4.x 用/api/v4/emqx_prometheus5.x 用/api/v5/prometheus/stats指标有Grafana 面板空白字段名不匹配或数据源变量没选对在 Explore 手敲一句 PromQL 验证字段连接数突然为 0Prometheus 重启后丢失了历史数据但没有时间范围问题检查 Grafana 时间范围是否太短或者聚合窗口太大5.3 落地之后我认为值得提前想清楚的事如果把监控接入当成“装个 Prometheus 导入模板”就完事那基本等于白做。真正的收益来自你有没有把监控数据变成决策依据。我建议你落地完这套之后下一步至少做三件事一是把告警规则逐步补上。连接数超过预估、队列堆积超过 5000、节点 CPU 持续超过 85%这些都是值得告警的边界。EMQX 的堆积问题往往不是瞬时爆发的而是默默涨上去的没有告警根本发现不了。二是把历史数据保留周期定好。Prometheus 默认本地存储大约留 15 天如果你的平台对“上一周的消息量”有复盘需求就提前规划远端存储或者接受限制。别到要查数据的时候才发现早被覆盖了。三是把 dashboard 固定成团队统一版本。几个人各导各的模板面板样式五花八门遇到问题对图都不好对。用 Provisioning 的方式把 dashboard 的 JSON 放进配置目录管理这样换人、换环境都能还原同一套视图。我个人在实际操作中的体会是EMQX 接入 Prometheus 和 Grafana 这件事最大的成本不在安装而在理解指标和业务之间的关系。你花了时间把每个字段背后代表的意义吃透后面的运维才会顺。先跑通、再调优、最后沉淀出自己的面板和告警规则这才是完整的落地路径。