十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Zabbix监控Nginx实战:从stub_status到UserParameter的完整链路

Zabbix监控Nginx实战:从stub_status到UserParameter的完整链路 先讲一个我实际遇到过的场景。某天业务方反馈“接口变慢了”我们在 Zabbix 上看 Nginx 所在主机CPU 不高、内存不高、连接数也不高主机可用性一直是绿色。但真实情况是后端 upstream 里的一个节点已经挂了Nginx 进程还活着却在反复等待这个不可达节点超时。那台机器的监控图上你几乎看不到任何异常因为当时我们只监控了“进程存活”和“系统资源”没有采集任何 Nginx 自身的状态数据。这件事过后我最大的体会是监控 Nginx 的核心从来不是“agent 装没装上”而是你有没有把 Nginx 的状态数据可靠地采出来并且让它成为能辅助判断的依据。agent 只是通道真正有价值的是通道里跑的指标以及围绕这些指标建立的阈值、图形和告警。这篇文章我从实际落地角度把 Zabbix 监控 Nginx 时涉及的安装、配置、agent 接线、模板对接、排障链路和长期使用建议完整梳理一遍。你会发现单次跑通不难难的是让这套监控真正稳定可用。1. 监控 Nginx 不等于 agent 跑起来先定义你要采的四个维度很多人接到“把 Nginx 监控起来”这个需求时第一反应是给机器装上 zabbix-agent然后在 Zabbix Server 前端添加主机、链接模板。看起来链路通了但过几天复盘时会发现监控数据并没能回答任何业务问题。原因很简单**Nginx 监控不是“有没有装 agent”而是“有没有把该采的状态数据采到”。**如果采样层是空的后面所有图形和告警都是空转。1.1 进程存活只是“没宕机”不是“在正常服务”Zabbix 默认的主机可用性监控只能告诉你这台机器网络通不通、agent 有没有响应。它不能告诉你 Nginx 是否在接受新连接也不能告诉你当前请求是不是堆积在处理队列里。在生产环境里进程活着和业务正常是两码事。Nginx 可能因为 worker 连接数打满、upstream 后端全部不可用、共享内存耗尽等原因出现“进程还活着但服务已经劣化”的状态。只看进程存活等于监控了个寂寞。所以第一步先把监控维度从“主机可用性”提升到“Nginx 运行状态”。这通常依赖 Nginx 自带的 stub_status 模块或者更强的 vts、prometheus exporter 方案。1.2 Nginx 自带状态页stub_status 与更现代的替代方案stub_status 是 Nginx 官方内置模块编译时加--with-http_stub_status_module就能启用。如果你用的是发行版自带的 Nginx很多发行版默认也编译了这个模块。启用后访问指定 URL会得到这么一段输出Active connections: 6 server accepts handled requests 10 10 125 Reading: 0 Writing: 2 Waiting: 4这段信息量比你以为的大得多Active connections当前活跃连接数包括正在处理的和等待中的。acceptsNginx 启动以来累计接受的客户端连接数。handled成功处理的连接数。正常情况下它应该等于或接近 accepts。requests累计处理的请求数。Reading正在读取请求头的连接数。Writing正在写响应给客户端的连接数。Waiting空闲 keepalive 连接数。如果只是追求简单stub_status 完全够用。它的问题是信息维度偏“连接层”看不到状态码分布、upstream 延迟、缓存命中率这些更高层指标。在社区实践里后续演进通常有两个方向一个是 Nginx 的 vts 模块能输出更丰富的 JSON 数据但要重新编译 Nginx另一个是引入 prometheus nginx-exporter走 Prometheus 生态再想办法接入 Zabbix。对绝大多数团队来说先把 stub_status 这条链路跑通已经能解决 80% 的监控需求。1.3 一个最小可落地的监控指标清单我建议第一次做 Nginx 监控时不要贪多。先采这 7 个指标稳定运行一个月再考虑状态码、延迟和自定义业务探活指标含义主要用途nginx.active当前活跃连接数看瞬时压力nginx.accepts累计接受连接数看流量的绝对值nginx.handled累计处理连接数对比 accepts发现握手异常nginx.requests累计请求数看请求趋势容量预估nginx.reading读请求头的连接数偏低时通常正常持续高说明读请求慢nginx.writing写响应连接数持续高说明响应写不出去nginx.waiting空闲 keepalive 连接数偏低说明连接很快被回收这里要注意accepts、handled、requests 是累计值。Zabbix 里要用“变化率”或者依赖 Zabbix 自带预处理做差值否则你看到的是一条一直往上的增长曲线而不是每秒速率。这个细节很多人第一次配置时都会漏掉。2. 安装与接线Zabbix Server、Agent 与 Nginx 的三方关系Zabbix 监控 Nginx 的场景里看起来是“Zabbix 监控 Nginx”实际上涉及三个角色Zabbix Server、Zabbix Agent、Nginx 服务。三者关系不搞清配置时很容易配错方向。2.1 版本选择Zabbix 7.0 LTS 还是 6.xDocker 还是包安装当前讨论里 Zabbix 7.0 LTS 和 Zabbix 6.0 LTS 的呼声都比较高。我的倾向是新环境直接上 Zabbix 7.0 LTS它是官方长期支持版本前端体验、模板管理、预处理能力都有增强。存量环境如果已经在 6.x 稳定跑着不必为了追新而升级。监控系统的第一原则是稳定不是新功能。如果只是学习和小规模验证用 Docker 部署 Zabbix Server 可以快速看到效果。官方提供了现成的容器编排文件MySQL/PostgreSQL Zabbix Server Zabbix Web 的组合能几分钟起一套。生产环境我建议用包安装或者离线包。原因很朴素包安装的升级路径更清晰日志目录更常规出问题时更容易用系统服务工具调试。Docker 部署在生产里不是不行只是你需要把数据卷、备份、版本升级这些问题提前想清楚。2.2 Agent 是被动采集还是主动上报Zabbix Agent 有两种工作模式被动模式Zabbix Server 主动连 Agent 的 10050 端口发起 key 查询。主动模式Agent 按配置的 ServerActive 地址主动连 Zabbix Server 的 10051 端口上报数据。对于监控 Nginx 这个场景我建议第一台机器先用被动模式跑通。原因是排查链路短server 侧的 zabbix_get 命令可以直接验证 key 能不能取到值问题更容易定位。等主机数量多了比如几十上百台再切主动模式分摊 Server 的轮询压力。还有一个容易踩的点主动模式下Agent 端配置的Hostname必须和前端创建主机时填写的“主机名称”完全一致否则上报数据会失败。被动机则主要看前端配置的 agent 接口 IP 和端口对不对。2.3 主机组、主机与模板先建立最小联通在 Zabbix Server 前端操作时通常按这个顺序创建主机组例如Nginx-Servers。“数据采集 - 主机 - 创建主机”填写主机名、可见名、选择主机组。配置 agent 接口填写被监控机 IP 和端口默认 10050。链接模板。如果还没有现成模板先不要链接任何模板直接手动添加一个监控项试试。这里强调“先手动添加一个监控项”是想让你先排除模板干扰。很多同学一开始就链接模板结果数据没出来分不清是 agent 配置问题、模板 key 和 agent 对不上还是前端配置问题。先把一条 key 跑通再套模板整个流程会清晰很多。3. 把状态数据接到 AgentUserParameter 的真实工作过程这是整篇文章最核心的一章。前面那些准备工作最终都要通过 UserParameter 把 Nginx 状态数据变成 Zabbix Agent 能返回的 key。3.1 先让 Nginx 暴露状态页并限制访问来源在 Nginx 配置里加一个 location。假设你的 Nginx 和 Zabbix Agent 在同一台主机上最简单的配置是这样location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; }然后 reload 配置nginx -s reload用 curl 验证一下能不能拿到状态页curl http://127.0.0.1/nginx_status这一步是命门。如果 curl 都拿不到输出后面所有配置都是空中楼阁。常见的失败原因包括Nginx 编译时没带 stub_status 模块、location 写错了、allow/deny 顺序错导致本机也被拒绝。如果你的 Agent 和 Nginx 不在同一台主机那就不能只 allow 127.0.0.1而要把 Agent 所在机器的内网 IP 加入 allow。不过我更建议把 agent 和 Nginx 放在同一台机器既减少网络暴露面也减少排查链路。3.2 用一条命令验证解析结果再写 UserParameter拿到状态页输出后先用命令行把要采集的字段解析出来。比如要采集活跃连接数curl -s http://127.0.0.1/nginx_status | awk /Active connections/{print $3}要采集累计请求数curl -s http://127.0.0.1/nginx_status | sed -n 3p | awk {print $3}注意不同 Nginx 版本的 status 输出格式偶尔会有差异。所以不要凭记忆写解析命令先手工执行一遍确认输出正确再写进配置文件。然后创建 UserParameter 配置文件。常见路径是/etc/zabbix/zabbix_agentd.d/nginx_status.confUserParameternginx.active,curl -s http://127.0.0.1/nginx_status | awk /Active connections/{print $3} UserParameternginx.accepts,curl -s http://127.0.0.1/nginx_status | sed -n 3p | awk {print $1} UserParameternginx.handled,curl -s http://127.0.0.1/nginx_status | sed -n 3p | awk {print $2} UserParameternginx.requests,curl -s http://127.0.0.1/nginx_status | sed -n 3p | awk {print $3} UserParameternginx.reading,curl -s http://127.0.0.1/nginx_status | awk /Reading:/{print $2} UserParameternginx.writing,curl -s http://127.0.0.1/nginx_status | awk /Writing:/{print $4} UserParameternginx.waiting,curl -s http://127.0.0.1/nginx_status | awk /Waiting:/{print $6}这里有两个隐蔽问题。第一curl命令此时是 Zabbix Agent 进程执行的Agent 默认以zabbix用户运行。如果zabbix用户的环境变量 PATH 里没有 curl命令会失败。稳妥做法是在配置里写 curl 的绝对路径比如/usr/bin/curl。先执行which curl确定路径。第二Agent 配置里有Timeout参数默认一般 3 秒或 5 秒。如果这条命令执行超过超时时间Zabbix Server 会显示采集失败。curl 访问本机 Nginx 状态页通常毫秒级返回如果你的机器负载很高导致命令超时那首先要解决的是系统层面的问题而不是盲目调大 Timeout。改完配置后重启 agentsystemctl restart zabbix-agent然后可以用 agent 自带的自检命令确认 key 是否可用zabbix_agentd -t nginx.active如果返回ZBX_NOTSUPPORTED说明 key 没注册上或者命令解析报错。如果返回数值说明 agent 侧这一层已经通了。3.3 模板里的 key 和 agent 端的 key 必须严格对得上这里是最容易被忽略的一环。你在前端导入官方 Nginx 模板后模板里的监控项会定义一批 key。比如官方模板可能用nginx.connections.active而你手写的 UserParameter 是nginx.active。两边对不上Zabbix Server 去 agent 取数据时agent 根本不知道nginx.connections.active是什么。正确的做法是在前端“模板 - 监控项”里找到模板定义的 key 列表。到 agent 端 UserParameter 配置里把 key 名改成和模板一致的。改完重启 agent再用zabbix_agentd -t 模板key测试。很多人在这一步反复折腾其实问题就一个模板 key 和 agent key 的名字没有对上。没有哪个神级模板能自动识别你的自定义 UserParameter模板只是一个定义层采集层必须手动对齐。3.4 超时、权限和 curl 路径三个最容易踩的隐形坑把最容易踩的三个坑单独列出来每个都值得记一下权限问题Agent 以zabbix用户运行如果 Nginx 状态页做成了基于文件的 socket 访问或者有限制系统用户的目录权限命令就会失败。curl 路径问题写相对curl命令时系统服务进程的 PATH 比你登录 shell 的 PATH 短很多。这是初学者最容易遇到的“命令行明明能跑agent 一调就失败”的经典原因。变量和引号问题UserParameter 值里如果包含管道、引号建议先用单引号或双引号包裹完整命令避免被 Agent 配置解析器误切。4. 前端配置与图形化怎么知道数据是真的进来了Agent 侧配置完后回到 Zabbix Server 前端把这批数据变成可见的监控项和图形。4.1 监控项、历史存储、预处理和单位如果你没有链接任何模板就需要手动创建监控项。在前端“数据采集 - 监控项 - 创建监控项”里关键字段是名称写清楚比如Nginx Active Connections。类型默认 Zabbix agent。键值填 agent 端定义的 key比如nginx.active。主机接口选择 agent 接口。数据类型一般是数字无符号。单位连接数可以留空请求数如果要展示为速率需要用预处理或者 Zabbix 的差值算法。关于单位有个容易出问题的小知识如果填了单位BZabbix 会按字节格式显示数值如果填s可能会把你的数字当成秒来显示。对连接数这种无量纲指标建议单位留空。如果是累计值指标比如 accepts、requests我建议在监控项里只存原始累计值然后在图形里用 Zabbix 的函数做变化率展示。这样数据源完整后续想按天、按小时看累计量也能算。历史数据保留周期和趋势数据保留周期建议保持默认。除非你的磁盘特别紧张否则不要为了省空间把历史周期压得太短否则排查问题时你会发现图表里全是“毛刺”没有细节。4.2 图形和数据展示的常见偏差配置完监控项后先去“检测中 - 最新数据”页看有没有数值进来。这一步能直接判断整条链路是否通了。如果最新数据里能看到值接下来创建图形进入“数据采集 - 图形 - 创建图形”。选择刚才创建的几个监控项。图形类型默认“正常”即可。刷新图形页面看到曲线开始波动说明可视化层已经 OK。这里常见的偏差是数值永远是一个固定值比如requests一直是一条横线。这往往不是你采集失败了而是你把这几个累计值直接当成“速率”画出来了。真正的速率曲线需要在图形里配置监控项时勾选函数比如用change()、rate()或者min()配合时间周期。4.3 从单个 host 到多 host 批量接入单台主机跑通后再做批量接入。推荐思路把这批自定义 UserParameter 文件通过配置管理工具下发到所有 Nginx 机器然后在 Zabbix 前端把模板链接到新主机。如果不同 Nginx 实例的 status 路径或端口不一致可以用宏来解决比如在模板里把 key 定义成带参数的形式再把 URL 作为用户宏维护。简单场景下先用统一路径http://127.0.0.1/nginx_status是最省事的。模板的价值不是让你不用写 UserParameter而是把“监控项定义、图形、触发器”统一成可复制资产。真正到多主机场景你还是需要确认每一台机器上的 UserParameter 是一致的。5. 数据不到时的排查链路从现象到根因监控系统最耗时的不是配置而是排障。下面这条排查链路是基于同类问题反复实操总结出来的遇到 Nginx 监控数据出不来时可以按顺序走一遍。5.1 按“本地命令 → Agent → Server → 前端”的顺序排查我一般按照这个顺序从底层往上层查本地命令在被监控机上手动执行 UserParameter 里那条命令确认 curl 能访问、awk/sed 解析正确。Agent 侧执行zabbix_agentd -t key确认 agent 能返回数值。这一步能隔离大部分配置和权限问题。Server 侧在 Zabbix Server 机器上用zabbix_get主动拉一次 keyzabbix_get -s 被监控机IP -p 10050 -k nginx.active如果能返回数值说明 server 和 agent 之间的网络和协议都正常。前端侧检查“最新数据”里监控项有没有报错比如Not supported或Timeout。这四步做完80% 的问题都能定位到具体层。5.2 常见的五类根因和对应处理结合实操经验最常遇到的是这五类问题现象根因处理方式zabbix_agentd -t返回 Not supportedUserParameter key 没注册或命令写错检查配置文件路径、语法重启 agent手动命令正常agent 调用失败PATH 里没有 curl 或权限不足写绝对路径/usr/bin/curl检查 zabbix 用户权限zabbix_get拉不到值防火墙挡了 10050或前端主机 IP 配置错放通端口核对 agent 接口配置前端显示 Not supported模板 key 与 agent key 不一致对齐模板里的 key 名和 UserParameter 里的 key 名数据有但图形断断续续Agent Timeout 太短或服务器压力大先查负载再考虑调 Timeout5.3 版本变化与新特性带来的兼容注意点Zabbix Agent 和 Zabbix Server 之间是存在兼容性边界。老版本 Server 配新版本 Agent或者反过来都可能在加密、协议字段上出问题。所以版本策略要保守一点要么 Server 和 Agent 用同一大版本的主流小版本要么先在一台测试机上验证兼容性再铺开。生产环境最怕的就是“监控系统本身成了新的不稳定因素”。另外Zabbix 7.0 之后模板体系更强调独立模板和宏的使用。如果之前已经在老版本上手动建过一套 Nginx 监控项升级后不一定能无缝迁移要在测试环境里先跑一遍模板导入导出确认 key 和图形不丢。6. 监控有价值关键在于阈值、聚合和长期维护最后一步也是很多团队最缺的一步数据采集上来了怎么让它真正成为决策依据。6.1 先积累数据再定告警阈值我强烈不建议第一天就给连接数设死一个告警阈值比如“大于 2000 就告警”。正确的做法是先采集至少一周到一个月的数据。在图形里看这组指标的日常基线。找到峰值区间再根据 P95 或 P99 设定告警阈值。阈值一定得基于你自己的业务。有的业务高峰期 active connections 到 2 万也没事有的业务 2000 就扛不住了。不看自己的数据分布就设阈值不是监控是碰运气。6.2 连接数、请求数不够配合日志和 upstream 才能定位容量问题回到文章开头那个场景Nginx 进程活着但服务变慢。如果你只监控了 active connections 和 requests你可能还是看不到问题因为 Nginx 自己并不慢慢的是它背后的 upstream。stub_status 提供的信息有限。要更深入排查容量和质量问题至少还需要access log 里的状态码分布4xx 和 5xx 比例突增往往是业务或依赖出问题的信号。upstream_response_time这是反向代理场景最重要的指标之一能直接看出后端响应耗时。Nginx 错误日志连接超时、上游主动断开、worker_connections 不够、文件描述符耗尽都会在 error log 里留下线索。这些不是 Zabbix 一个模板能完整覆盖的。更常见的工程化方案是Zabbix 监控主机层和进程层指标再搭配 Nginx 日志的集中采集分析或者引入 vts/prometheus exporter。每一层解决每一层的问题不要指望一个 agent 全包。6.3 把这个场景沉淀成一套可复用的监控落地流程如果你只记住一件事就记住这个顺序**先固定指标再打通通道再做可视化最后才做告警。**顺序反了告警只会成为另一个噪声源。一个可复用的落地框架大概是先定义要采的指标。从 stub_status 的 7 个基础指标开始不要一上来加状态码、延迟。再让数据能采到。开 Nginx 状态页写 UserParameter用zabbix_agentd -t验证。然后接前端。创建监控项、图形确认最新数据有值图形有曲线。等数据积累到能看出趋势后再写触发器。告警先用 Info/Warning 级别试运行避免直接 High 刷屏。最后考虑扩展。从单台到批量从连接数到状态码到 upstream 延迟按需逐步加。这套流程适用面不只有 Nginx。任何用 Zabbix 监控中间件、数据库、应用服务的场景底层思路都是相通的先确认要采什么再确认采集命令能跑通最后把数据变成图形和告警而不是反着来。Nginx 的 stub_status 看起来简单但它背后那条链路足够让你把 Zabbix 的 agent、UserParameter、模板、监控项、触发器整套机制完整摸一遍。跑通它你会发现 Zabbix 监控其他中间件路径也差不远。
返回列表