ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Zabbix监控Nginx没数据?核心问题往往在状态页与agent采集链路上

Zabbix监控Nginx没数据?核心问题往往在状态页与agent采集链路上 上个月帮同事排查一套 Zabbix 监控 Nginx 数据一直为空的问题。一开始我们都把注意力放在 Zabbix Web 端反复检查模板、主机、宏折腾了一上午。最后才发现真正断掉的环节是 Nginx 的 stub_status 状态页根本没有暴露出来agent 自然也就拿不到任何数据。更让我意外的是同事的配置是从一篇两三年前的教程里抄来的那篇教程里的模板名称、agent 类型和现在的环境已经对不上。这不是个案。Zabbix 监控 Nginx 这件事最常见的坑不是 Zabbix 不会装而是安装配置流程里塞满了旧资料。所以下面我不打算只给一个固定命令序列而是想把 Zabbix 监控 Nginx 的链路重新拆一遍Nginx 怎么暴露状态agent 怎么读到数据模板怎么匹配以及当你拿到一台新机器时应该按什么顺序验证。核心判断只有一句——真正决定这套监控能不能跑通的往往不是 Zabbix 本身而是 Nginx 状态页、agent 采集和模板匹配这三个环节有没有全部连上。1. 先想清楚Zabbix 监控 Nginx 到底在监控什么1.1 表面是进程存活本质是连接和请求很多入门教程会把 Zabbix 监控 Nginx 简单理解成“Nginx 挂了就报警”。这个理解不算错但太单薄。Nginx 是应用入口它的价值不在于进程起没起来而在于它当前扛了多少连接、请求处理得是否顺畅、有没有异常堆积。Zabbix 之所以能监控 Nginx核心不是直接读进程状态而是通过 Nginx 自身的状态接口或模块拿到一组结构化指标。最常见的数据源是 Nginx 官方自带的 stub_status 模块。打开状态页后你会看到类似这样的一小段文本Active connections: 3 server accepts handled requests 12 12 15 Reading: 0 Writing: 1 Waiting: 2这几个数字的含义值得记住Active connections当前活跃连接数。acceptsNginx 启动以来成功接受的连接总数。handled成功处理的连接总数。正常情况下 accepts 和 handled 应该接近。requests总请求数。Reading / Writing / Waiting分别表示正在读请求头、正在写响应、以及空闲 keep-alive 连接的数量。这些指标能帮你看清什么比如 Reading 长时间很高说明请求堆积在读取阶段背后可能是客户端没有把请求发完整Waiting 大量存在不是坏事只能说明 keep-alive 连接占着资源accepts 和 handled 差距持续增大则可能说明有连接在中间环节被丢掉。1.2 为什么很多“监控没数据”其实和 Zabbix 无关排查过几次就会发现Zabbix 监控 Nginx 没数据绝大多数原因不在 Zabbix要么是 Nginx 状态页没开启要么是状态页返回的是 HTML 而不是纯文本要么是 agent 访问不到状态页要么是模板里的宏路径和实际路径不一致。Zabbix 本身只是在按固定周期向 agent 要数据agent 再去请求 Nginx 状态页。这一条数据链上有任何一个环节断了仪表盘就永远是空的。所以我建议把这条链路拆成三段来理解Nginx 负责提供数据agent 负责搬运数据Zabbix 负责展示和告警。后两段的问题通常都有日志可查反而是第一段最容易被人忽略。很多“监控没数据”的案例其实和你选的模板、版本的关联没有想象中那么大问题往往出在数据源这一层。2. Nginx 侧的状态页配置先把数据源打开2.1 先确认模块再改配置顺序不要反Nginx 状态页依赖 http_stub_status_module 这个模块。问题在于不是所有 Nginx 环境都默认包含它。源码编译安装时如果没有带 --with-http_stub_status_module后面想加模块就得重新编译发行版仓库里的 nginx 通常已经包含这个模块但不同发行版、不同仓库之间也可能有差异容器镜像则更不一定一些精简镜像会把用不到的模块裁掉。所以第一步是确认模块存在。常见做法是查看编译参数nginx -V 21 | tr \n | grep stub_status如果输出里能看到 http_stub_status_module说明模块没问题。如果什么都没有就不要继续往下配状态页了先解决模块问题。否则你配置再正确curl 访问时也只能看到 404。注意有些系统里 nginx 不在 PATH 中可能需要写全路径比如/usr/local/nginx/sbin/nginx -V或者先执行which nginx确认一下。2.2 一个稳妥的 stub_status 配置示例确认模块存在后再修改 Nginx 配置。常见的做法是在一个 server 块里加一个 location只让状态页从指定路径访问server { listen 80; server_name _; location /nginx_status { stub_status; allow 127.0.0.1; allow 192.168.10.0/24; deny all; } }这里有几个细节要说明。location /nginx_status是精确匹配避免掩盖其他路径规则stub_status;是常见写法如果你看到的旧教程里写的是stub_status on;通常也能兼容但更推荐按当前版本的标准写法来allow 和 deny 用来限制来源 IP避免状态页暴露到公网。虽然状态页内容看起来不敏感但泄露给外界等于给攻击者多一个信息采集入口没有理由不做限制。写完配置后先检查配置再重载nginx -t nginx -s reload # 如果使用 systemd 管理也可以写成 systemctl reload nginx然后用 curl 验证curl -s http://127.0.0.1/nginx_status如果能看到开头那段纯文本说明 Nginx 侧已经通了。注意curl 的来源 IP 要和 allow 规则匹配否则你会看到 403。2.3 容器化和非默认端口环境的特殊点如果你的 Nginx 跑在容器里情况会稍微复杂一点。agent 要么和 Nginx 在同一个容器内要么通过容器 IP 或映射端口访问状态页。容器内的 Nginx 如果只监听了容器内部端口agent 在宿主机上直接 curl 127.0.0.1 是拿不到响应的。这类问题用 curl 验证时最容易暴露但很多人会误以为是自己配置写错了。另外状态页不一定只能放在 80 端口。有的环境为了安全和便于管理会把状态页放在 8080 或单独一个 server 块里。这样的设计没问题但模板里的宏就要跟着改。这里的重点是先想清楚 agent 要从哪个地址访问 Nginx然后保证这个地址上的 TCP 连通性和 ACL 都允许。不要只在 Zabbix 里把宏改来改去主机上却访问不到。我在很多环境里见过一种最隐蔽的错误状态页本身配置正确但 allow 规则只放行了 127.0.0.1agent 却通过内网 IP 去访问状态页。agent 请求时Nginx 看到的来源 IP 是内网地址命中 deny all于是返回 403监控项自然拿不到数据。所以配置 allow 时要想着 agent 会从哪个 IP 过来而不是只写 127.0.0.1。3. Zabbix agent 这一层不是安装了就行3.1 配置 Server 地址和 Hostname一致性是第一原则Nginx 状态页通了之后才轮到 agent。agent 安装本身不复杂麻烦的是配置。以最常见的 zabbix-agent 为例配置文件里几个关键参数一定要理解Server192.168.10.20 ServerActive192.168.10.20 Hostnameweb01Server 和 ServerActive 不是一回事。Server 是被动模式下允许从 Zabbix Server 拉取 item 的地址白名单ServerActive 是主动模式下 agent 向哪个 Zabbix Server 或 Proxy 上报数据的地址。如果你只配置了 Serveragent 就会等 Server 来问如果你用了主动模式ServerActive 也要填。很多旧教程只写一个值换到新环境就出问题。比这更容易出错的是 Hostname。Zabbix Web 端添加主机时填的主机名必须和 agent 配置里的 Hostname 保持一致。如果 Web 端写的是 web01agent 里配的是 nginx-web-1那么即使在 Zabbix 里能看到主机监控项也始终是 no data。在新版本 agent 里你还会看到HostnameItemsystem.hostname这样的配置意思是让 agent 用系统本身的 hostname 作为上报名称。这个机制可以避免手工维护 Hostname但前提是系统 hostname 必须和 Zabbix Web 里的主机名一致。所以不管用哪种方式原则都是同一个两边名字要对上。3.2 agent 与 agent2模板和 key 可能不一样这里要说一个“和过去不一样”比较明显的点现在 Zabbix 官方推荐使用 Zabbix agent 2也就是 agent2。agent2 不仅在采集能力上更丰富还支持一些内置插件但对应的模板、监控项 key 和旧 agent 不完全一样。在 Zabbix Web 里搜索 Nginx 时你可能会看到多个模板有些名字类似 Nginx by HTTP有些类似 Nginx by Zabbix agent 2。如果你在主机上装的是 agent2却链接了旧 agent 版本的模板可能会出现 unsupported item。反过来也一样。所以我的建议是在链接模板之前先打开模板里的监控项预览看它使用的采集类型是 Zabbix agent、HTTP agent还是依赖 agent2 插件。确认它跟你实际安装的 agent 类型对得上再链接。这一步只要花两分钟却可以省掉后面一晚上的排查时间。agent 和 agent2 的服务名也不一样常见的有 zabbix-agent、zabbix-agent2系统服务名可能是 zabbix-agentd.service 或 zabbix-agent2.service。启动服务后用systemctl status看一下是否 active再看一眼日志路径常见的是/var/log/zabbix/下面。出现问题时日志里通常直接会告诉你 key 不支持还是连接失败。3.3 用 zabbix_get 快速验证采集链路在 Web 端排查前可以先在 Zabbix Server 上用 zabbix_get 做一次最直接的验证确认 agent 是否正常工作zabbix_get -s 192.168.10.11 -k agent.ping如果返回 1说明 Server 能连上 agent。如果返回值不是 1就别急着去 Web 端看模板先解决网络、端口和 Hostname 问题。agent.ping 是通用探活 key验证通过后再去模板里找到你想测的监控项 key比如和 Nginx 状态页相关的 key继续用 zabbix_get 测试。不同版本、不同模板的 key 名称会有差异所以这里不列具体 key但思路是一样的先用 curl 确认状态页存在再用 zabbix_get 确认 agent 能取到值最后才去 Web 端看图表。链路从底层往上逐层打通比在界面上猜效率高得多。4. 在 Zabbix Web 端链接模板别被旧截图带偏4.1 模板名称已经变过好几轮Zabbix 的模板策略在过去几年变化很大。这次部署里我在模板列表里搜索 nginx出来的已经不是早期教程里那张截图上的名字了。官方模板按采集方式做了拆分有的走 HTTP agent有的走 Zabbix agent有的专门适配 agent2。这本身是好事但如果你照着一个两三年前的教程去选模板很可能选错。我的建议是以当前 Zabbix 版本实际加载的模板列表为准不要凭记忆点。链接模板后立刻去“监测 – 最新数据”里过滤这个主机等一到两个更新周期看有没有数据进来。如果 Zabbix 的刷新周期是 30 秒或 1 分钟通常几分钟内就能看到。另外一个主机通常只需要链接一个对应当前采集方式的 Nginx 模板不需要把所有 Nginx 模板全链接上。链接多个模板并不会让数据更丰富反而会让监控项冲突、重复告警排查起来也更乱。4.2 宏参数路径、协议、端口都是变量模板链接后还有一层容易被忽略宏参数。官方 Nginx 模板里通常会定义一组宏用来告诉 agent 去哪个地址、哪个路径、用什么协议获取状态页。常见宏名可能包括{$NGINX.SCHEME}、{$NGINX.PORT}、{$NGINX.STUB_STATUS.PATH}具体名称以你当前模板为准。它们的作用就是把状态页的访问信息从监控项中抽出来这样同一套模板可以复用在不同的 Nginx 主机上。如果你的状态页地址不是默认值就不用改监控项直接在主机层级覆盖宏就行。比如状态页路径是 /nginx_status 而不是 /status就在主机的宏里把对应宏改成实际路径。改完后等下一次采集生效再看最新数据。要注意的是宏的生效范围有层级全局宏、模板宏、主机宏。主机宏优先级最高。如果模板里已经定义了默认值主机上没改也没关系但如果状态页地址做了修改一定要记得改对应主机的宏而不是只在模板里改一个默认值因为模板默认值会影响所有链接该模板的主机。还有一个容易出错的地方状态页地址如果是 https但宏里用的是 http监控项会一直返回错误。这种问题在视觉上非常隐蔽因为 Nginx 和 agent 都正常只有协议不匹配。4.3 验证模板是否能出数据链接模板和配好宏之后不要直接离开页面。花一分钟做两件事第一到主机监控项列表里看有没有出现红色 error 状态的监控项第二到最新数据里过滤该主机确认有非空数据。如果看到 error 状态的监控项先点击进去看错误信息。常见的有 unsupported item key、Cannot connect to [...]: 10060、Connection refused 这类。每一条错误信息其实都指向了数据链路的具体环节比你在外面猜模板要快得多。如果最新数据里有值但看起来不对比如 Reading 是 0、Writing 是 0也不要慌先用 curl 手动看一次状态页确认源数据里就是这些值然后判断是 Nginx 本身空闲还是采集路径不对。如果源数据是对的Zabbix 只是如实展示不用改 Zabbix。5. 没数据的排查链路按顺序查别乱试5.1 四个环节从上到下检查如果你最终面对的是一台没数据的 Nginx 主机不要先怀疑 Zabbix更不要反复重新链接模板。按下面的顺序逐层排查通常能在十分钟内定位问题。第一层Nginx 状态页是否可访问。curl -s http://127.0.0.1:80/nginx_status如果 curl 能返回纯文本进入下一层。如果返回 403、404 或 HTML 页面问题在 Nginx 侧。第二层agent 能否读到状态页。注意 agent 的运行身份和权限。你可以切换到 agent 运行用户或者用 sudo 模拟执行同样的 curl 命令确认 agent 视角下能访问。如果 agent 在容器里还要确认容器网络。第三层Server 和 agent 之间是否连通且 Hostname 匹配。zabbix_get -s agent_ip -k agent.ping如果 zabbix_get 返回 1说明网络层通。然后再确认 Web 端主机名和 agent Hostname 一致。第四层模板宏和监控项是否匹配。打开监控项列表查看具体监控项的 key、宏替换后的实际地址用测试功能跑一次。如果返回错误根据错误信息调整宏。这个顺序的核心思路是先确定是哪一层坏了再决定修哪里。不要在不知道哪一层出问题的时候改配置改来改去只会让状态更乱。5.2 高频错误对照表下面这张表基本覆盖了 Zabbix 监控 Nginx 时最容易遇到的几类现象现象常见原因处理思路状态页 curl 返回 404没有配置 location 或模块缺失先查 nginx -V 里的 stub_status 模块状态页 curl 返回 403allow/deny 没有放行 agent 来源 IP调整 allow 规则思考 agent 从哪个 IP 访问监控项显示 unsupported itemagent 版本或模板类型不匹配确认是 agent 还是 agent2换对应模板或 key最新数据一直是空Hostname 不匹配、宏路径不对、采集周期长检查主机名一致性测试宏替换后的地址监控项返回 Connection refusedagent 未启动、端口不通、防火墙拦截systemctl status 看服务再用 zabbix_get 验证状态页返回的是 HTML 而非纯文本location 配置被其他规则截获检查 server 块顺序确认精确匹配位置这张表不是让你背下来而是给你一个参考坐标。遇到问题时先看现象再判断属于哪一层然后去对应位置检查。5.3 沉淀一个“四层验收清单”最后一个能长期复用的经验把 Zabbix 监控 Nginx 的链路固定成一张验收清单每次新接入一台 Nginx 主机时按顺序过一遍。Nginx 状态层模块存在、location 配置正确、curl 返回纯文本、allow 已放行 agent 来源 IP。Agent 采集层服务已启动、配置了正确的 Server/ServerActive、Hostname 与 Web 端一致、zabbix_get 验证 agent.ping 返回 1。Server 接入层Web 端主机存在、agent 接口可达、主机名匹配。模板匹配层链接了适配 agent 类型的 Nginx 模板、宏路径/协议/端口正确、最新数据出现非空值。这个清单不是固定不变的但它能帮你把一次复杂的排查变成一次顺序的确认。以后不管是三台机器还是三十台机器先让这种验证顺序变成肌肉记忆再谈自动化。6. 适用边界这套方案不是所有 Nginx 环境都适合6.1 适合谁Zabbix 监控 Nginx 这套方案适合的场景其实很清楚你已经在用 Zabbix手里是一批长期存在的虚拟机或物理机核心关注的是连接数、请求数、握手状态等基础指标。这种情况下引入一套新的监控系统成本远大于收益直接在 Zabbix 里接 Nginx 模板是最顺的路。从我个人经验看当一个团队已经用 Zabbix 管了几百台机器再为了 Nginx 单独部署一套 Prometheus、Grafana反而不划算。不是因为 Prometheus 不好而是你的告警、权限、仪表盘、值班流程都已经长在 Zabbix 上了新增一套系统意味着要同时维护两套监控体系的账号、存储和告警规则。6.2 不适合谁反过来如果你的环境是大量短生命周期容器Nginx 实例像 Pod 一样随时扩缩容Zabbix 这种以主机为单位的管理模型就会变得很吃力。每来一个新实例都要创建主机、链接模板、维护 Hostname规模一大这些动作本身就是运维负担。另外如果业务需要按 URL、按状态码、按 upstream 做细粒度 SLA 分析单靠 Zabbix 的 Nginx 状态页数据也不够。状态页给的是连接数和请求总数拿不到每个接口的响应时间分布。这种需求更适合让 Nginx 输出 access log 结构化、再送进时序数据库或者日志系统或者直接采用具有服务发现能力的监控方案。这不是说 Zabbix 不能做扩展而是说你要先判断值不值得。任何方案都有维护成本Zabbix Nginx 监控的优势是简单直接代价是深度有限。认清这个边界比盲目堆监控项更重要。6.3 重要的不是某一个命令而是适应变化的能力回到标题里那半句“和过去有一点不同”。这句话其实很适合用来概括这类监控方案的常态Nginx 的编译参数在变agent 从旧版走向 agent2模板名称和宏定义在变安装方式从裸机走向容器。过两年你再回头看今天这篇文章里的具体配置很可能又有出入。但有一点不会变数据从 Nginx 到 agent 再到 Server 这条链路的逻辑是稳定的。你只要掌握了“先 curl 状态页、再 zabbix_get 探活、最后看模板宏”的验证顺序无论版本怎么升级你都能在最短时间内判断出问题出在哪一层。这才是比某一条命令更有价值的东西。所以我的长期建议是不要只收藏某个版本的配置片段而是顺手把自己的环境、模板名称、宏定义、验证命令写成一个简短文档或脚本。下次再遇到 Nginx 监控没数据你不是回去翻旧教程而是打开自己的排查清单。回到开头那个案例。我们最后做的事情其实很简单把 stub_status 状态页配置好allow 规则放行 agent 来源 IP再把 Web 端主机名和 agent Hostname 改成一致。数据在第二个更新周期就出现了。整个过程没有任何悬案只是之前分散在不同教程里的经验没有串成一条完整的链路。Nginx 侧会变、Zabbix 会变、模板会变但验证顺序不会变。下次再看到最新数据为空时不要急着在界面上反复点先打开一个终端curl 一下状态页很多时候答案早就写在响应里了。
返回列表