这次我们来看一套很常见的运维组合:Zabbix 监控 Nginx。标题里专门提到了“克隆机子”,说明很多人的实际场景是先搭好一台 Nginx + Zabbix Agent 的模板机,然后直接克隆出多台,再统一接入监控。这个流程看着简单,但克隆之后经常出现主机名冲突、Nginx 状态页访问不到、Zabbix Agent 连不上服务器、监控数据对不上机器等问题。
这篇文章不会停在“能监控”这个层面,而是把 Nginx 状态模块配置、Zabbix Agent 安装、克隆机处理、模板导入、主机绑定、接口调用和批量接入全部串起来,给出可以直接照做的步骤和排查思路。
1. 核心能力速览
| 能力项 | 说明 |
|---|---|
| 监控对象 | Nginx 运行状态,包括连接数、请求数、握手数、读写状态 |
| 数据采集方式 | Nginx stub_status 状态页 + Zabbix Agent UserParameter |
| 推荐架构 | Zabbix Server 集中采集,Zabbix Agent 部署在被监控 Nginx 机器上 |
| 支持平台 | Linux 为主,Windows 下 Nginx 也能用类似方式采集 |
| 版本兼容 | 适用于 Zabbix 5.0 / 6.0 / 7.0 等主流版本,配置思路一致 |
| 是否支持批量 | 支持。克隆多台机器后,通过脚本或 API 批量注册主机 |
| 是否有 API | 支持。Zabbix JSON-RPC API 可完成主机创建、模板绑定、数据查询 |
| 启动方式 | Nginx 修改配置后 reload,Zabbix Agent 以 systemd 服务运行 |
| 主要门槛 | Nginx 需要带 stub_status 模块;Agent 与 Server 的 Hostname/IP 配置不能冲突 |
这套方案适合大多数已跑 Zabbix、需要监控 Web 服务状态的团队。如果只是想临时看 Nginx 数据,也可以直接 curl 状态页,但只有接入 Zabbix 才能保留历史曲线、配置告警和对接告警通知。
2. 适用场景与使用边界
Zabbix 监控 Nginx 解决的是三类问题:
- 连接数突增。Active connections 从几百跳到几千,你要知道是哪台机器、什么时候开始的。
- 请求量异常。accepts、handled、requests 三条曲线的增长速度可以反映业务流量变化。
- 状态页有机率。Reading、Writing、Waiting 能看出 Nginx 当前是空闲还是忙不过来。
适合谁用?运维工程师、SRE、还有需要批量管理多台 Web 服务器的同学。特别是虚拟机、容器化环境里 Nginx 实例一多,用 Zabbix 集中监控比逐个登录看状态页高效得多。
使用边界也要说清楚。stub_status 只提供基础指标,它没有 QPS 统计、没有响应码分布、没有 Upstream 后端健康信息。如果要更细的数据,需要更换为 nginx-module-vts 或者接入 Prometheus exporter。另外,凡是生产环境里的 Nginx 状态页,不要直接暴露到公网,必须用 allow/deny 限制访问来源,或者干脆只监听本机回环地址,由 Zabbix Agent 本机采集。
还有一个容易被忽略的点:采集 Nginx 状态本身对业务影响很小,但如果状态页被刷、被外部访问,就会泄露请求量和连接数等运行信息,所以安全边界要提前做好。
3. 环境准备与前置条件
以“一台 Zabbix Server + 多台 Nginx 业务机”的经典架构为例,列出环境清单:
| 组件 | 要求 | 说明 |
|---|---|---|
| Zabbix Server | 已部署,版本建议 6.0 或 7.0 LTS | 本文以 Web 界面操作 + API 为例 |
| Nginx 机器 | Linux,Nginx 1.10+ | 需要确认编译时带 http_stub_status_module |
| Zabbix Agent | 与 Server 同大版本 | Agent 2 也可以,配置方式类似 |
| 数据库 | MySQL / PostgreSQL | Zabbix Server 自带或独立部署 |
| 网络 | Server 与 Agent 的 10050 端口互通 | 如果有防火墙,需要放行对应源 IP |
克隆机场景还需要准备一台“模板机”。模板机上装好 Nginx、配置好状态页、装好 Zabbix Agent、调好 UserParameter,然后做快照或关闭后克隆。
先确认 Nginx 是否支持 stub_status:
nginx -V 2>&1 | grep http_stub_status_module能输出 http_stub_status_module 说明自带模块。如果是用系统自带的 nginx 包,一般默认开启。如果没输出,就需要重新编译或者改用其他采集方式。这一步一定要在最开始做,否则后面 Agent 配置得再好也没有数据源。
4. Nginx 状态页配置
4.1 修改 Nginx 配置
在 nginx.conf 的 http 块或独立的 server 配置里加一个状态页 location。强烈建议只监听本机回环地址,Zabbix Agent 也是本机采集,没必要开放到外部网卡。
server { listen 127.0.0.1:80; server_name localhost; location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; } }如果你的 Nginx 是 Docker 部署,状态页监听地址要考虑到容器网络。更稳妥的方式是让状态页监听 127.0.0.1,然后 Docker 端口映射只暴露给宿主机,Zabbix Agent 安装在宿主机或者以 sidecar 方式部署。具体以你实际拓扑为准,核心原则是不要让端口直接暴露到公网。
验证配置并重载:
nginx -t nginx -s reload4.2 验证状态页
curl http://127.0.0.1/nginx_status正常会输出类似格式:
Active connections: 2 server accepts handled requests 10 10 20 Reading: 0 Writing: 1 Waiting: 1含义如下:
| 字段 | 含义 |
|---|---|
| Active connections | 当前活跃连接数 |
| accepts | 累计接受的连接数 |
| handled | 累计处理的连接数 |
| requests | 累计请求数 |
| Reading | 正在读取请求头的连接数 |
| Writing | 正在写响应的连接数 |
| Waiting | 空闲 keep-alive 连接数 |
如果 curl 不到,先检查 Nginx 日志和是否真的 reload 成功。这里最容易出问题是:改的是默认 server 块,但实际请求没走到这个 server。
5. Zabbix Agent 安装与连接配置
5.1 Agent 安装
以 Zabbix 7.0 在 Ubuntu 上安装为例。先把官方仓库加上,再安装 zabbix-agent:
wget https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_7.0+ubuntu24.04_all.deb dpkg -i zabbix-release_latest_7.0+ubuntu24.04_all.deb apt update apt install -y zabbix-agent在 RHEL/CentOS/Rocky 上的安装方式:
rpm -Uvh https://repo.zabbix.com/zabbix/7.0/rhel/9/x86_64/zabbix-release-7.0-1.el9.noarch.rpm dnf install -y zabbix-agent如果是其他版本或系统,去官方下载页选对应仓库包即可,思路一样。
5.2 配置 Server 地址与 Hostname
编辑 /etc/zabbix/zabbix_agentd.conf,重点看三个配置项:
Server=192.168.10.10 ServerActive=192.168.10.10 Hostname=web-nginx-01- Server 是 Zabbix Server 的 IP,Agent 只接收来自这个地址的被动检查请求。
- ServerActive 是 Agent 主动上报时连接的 Server 地址。
- Hostname 必须唯一。Zabbix 用这个字段识别主机,克隆机器时如果 Hostname 一样,会在 Server 端显示为同一台机器,数据互相覆盖。
配置完启动并设置开机自启:
systemctl enable zabbix-agent systemctl restart zabbix-agent systemctl status zabbix-agent5.3 配置 UserParameter 采集 Nginx 状态
Zabbix 内置模板虽然叫 “Nginx by Zabbix agent”,但它依赖 nginx.status 系列自定义键值,我们需要在 Agent 端补上。在 /etc/zabbix/zabbix_agentd.d/ 下新建 nginx_status.conf:
UserParameter=nginx.status[*],/usr/local/bin/nginx_status.sh "$1"然后创建采集脚本 /usr/local/bin/nginx_status.sh:
#!/bin/bash METRIC=$1 CURL_BIN=$(command -v curl) NGINX_STATUS_URL="http://127.0.0.1/nginx_status" NGINX_STATUS=$($CURL_BIN -s "$NGINX_STATUS_URL" 2>/dev/null) case $METRIC in active) echo "$NGINX_STATUS" | grep 'Active' | awk '{print $3}' ;; accepts) echo "$NGINX_STATUS" | sed -n '3p' | awk '{print $1}' ;; handled) echo "$NGINX_STATUS" | sed -n '3p' | awk '{print $2}' ;; requests) echo "$NGINX_STATUS" | sed -n '3p' | awk '{print $3}' ;; reading) echo "$NGINX_STATUS" | grep 'Reading' | awk '{print $2}' ;; writing) echo "$NGINX_STATUS" | grep 'Writing' | awk '{print $4}' ;; waiting) echo "$NGINX_STATUS" | grep 'Waiting' | awk '{print $6}' ;; *) echo 0 ;; esac脚本赋予执行权限,并重启 Agent:
chmod +x /usr/local/bin/nginx_status.sh systemctl restart zabbix-agent在 Agent 本机可以先用 zabbix_agent2 自测键值,Zabbix Agent 2 用这个命令,Agent 1 则用 zabbix_agentd:
zabbix_agent2 -t nginx.status[active] # 或者 zabbix_agentd -t nginx.status[active]如果输出带 value 的部分,说明采集链路已经通了。在 Server 端也可以装 zabbix-get 来远程验证:
zabbix_get -s 192.168.10.20 -k nginx.status[active]输出一个数字就说明 Agent 连接正常、脚本正常、Nginx 状态页正常,三个环节全部打通。
6. 克隆机处理与批量接入
6.1 克隆后会遇到的问题
从模板机克隆出来的机器,一般会有四个问题:
- 主机名(hostname)相同。这会导致 Zabbix 端主机识别混乱。
- 网卡 IP 冲突或配置重复。需要改 IP 和网络配置。
- SSH 主机密钥相同。安全风险,建议重新生成。
- Zabbix Agent 配置里的 Hostname 相同。这是监控连接失败的直接原因。
6.2 克隆后必须做的四步
第一步,改主机名:
hostnamectl set-hostname web-nginx-02第二步,重新生成 SSH 密钥:
rm -f /etc/ssh/ssh_host_* ssh-keygen -A systemctl restart sshd第三步,改 IP。如果克隆后网络配置还指向模板机的 IP,会造成冲突。这里以 netplan 为例,编辑 /etc/netplan/ 下的 yaml 文件,把静态 IP 改成新机器规划好的 IP:
network: version: 2 ethernets: ens33: addresses: - 192.168.10.21/24 routes: - to: default via: 192.168.10.1 nameservers: addresses: - 192.168.10.2应用配置:
netplan apply第四步,修改 Zabbix Agent 的 Hostname,与模板机区分开:
sed -i 's/^Hostname=.*/Hostname=web-nginx-02/' /etc/zabbix/zabbix_agentd.conf systemctl restart zabbix-agent这四步做完,再检查一次 Nginx 状态页是否还能访问。有时候克隆机 Nginx 配置里绑定了旧 hostname 或旧证书路径,需要同步修正。检查命令:
nginx -t curl -s http://127.0.0.1/nginx_status6.3 批量处理思路
如果一次性克隆了五六台,逐台手改效率太低。可以准备一个初始化脚本,接收参数为新的 hostname 和新的 IP。脚本按顺序处理:改主机名、改 IP、重生成 SSH 密钥、改 Zabbix Agent Hostname、重启服务,最后输出验证结果。注意,改 IP 的操作一旦执行,SSH 连接会断开,脚本需要设计成先执行完本地改动再在最后一步重启网络,或者分两段跑。
7. Zabbix Server 端模板导入与主机绑定
7.1 确认模板
Zabbix 6.0 和 7.0 的模板库里自带 “Nginx by Zabbix agent” 模板。在 Zabbix Web 界面点击 “Data collection” -> “Templates”,搜索 Nginx,找到这个模板。如果没有,说明安装包没有带官方模板库,需要去 Zabbix 官网的 Git 仓库下载对应版本的模板 XML,然后通过 “Import” 按钮导入。
7.2 创建主机并绑定模板
在 Zabbix Web 界面操作路径:Data collection -> Hosts -> Create host。
填写内容:
- Host name:与 Agent 的 Hostname 保持一致,比如 web-nginx-02。
- Template:搜索并选择 “Nginx by Zabbix agent”。
- Interfaces:添加 Agent 接口,IP 填 Nginx 机器的地址,端口默认 10050。
保存后,主机状态会自动变为 Enabled。接下来等几分钟,查看 “Latest data”,如果能陆续出现 nginx.status 相关指标,说明 agent 连接、模板、采集全部正常。
7.3 验证数据链路
在主机详情页的 “Monitoring” -> “Latest data” 里过滤 nginx,会看到类似 nginx.status[active]、nginx.status[requests] 这样的条目。如果显示 No data,优先回到 Agent 机器上执行:
zabbix_agent2 -t nginx.status[active]如果 Agent 本机能取到值,而 Server 端没有数据,就要检查 Server 端配置的 Agent 接口 IP 是否正确,以及 Server 到 Agent 的 10050 端口是否通:
telnet 192.168.10.21 100508. 接口 API 与批量主机管理
Zabbix 提供 JSON-RPC API,适合在克隆场景下批量注册主机。先登录获取 token:
curl -s -X POST http://192.168.10.10/api_jsonrpc.php \ -H 'Content-Type: application/json' \ -d '{ "jsonrpc": "2.0", "method": "user.login", "params": { "username": "Admin", "password": "zabbix" }, "id": 1 }'返回结果里会有 auth token。拿到 token 后,创建主机可以选择直接绑定 “Nginx by Zabbix agent” 模板:
curl -s -X POST http://192.168.10.10/api_jsonrpc.php \ -H 'Content-Type: application/json' \ -d '{ "jsonrpc": "2.0", "method": "host.create", "params": { "host": "web-nginx-02", "interfaces": [ { "type": 1, "main": 1, "useip": 1, "ip": "192.168.10.21", "dns": "", "port": "10050" } ], "groups": [{"groupid": "2"}], "templates": [{"templateid": "10272"}] }, "auth": "你的认证令牌", "id": 1 }'注意,groupid 和 templateid 需要先通过 API 查询确认,每个环境的 ID 不同:
curl -s -X POST http://192.168.10.10/api_jsonrpc.php \ -H 'Content-Type: application/json' \ -d '{ "jsonrpc": "2.0", "method": "template.get", "params": { "output": ["templateid", "host"], "filter": {"host": ["Nginx by Zabbix agent"]} }, "auth": "你的认证令牌", "id": 1 }'批量接入的通用思路是:写一个循环脚本,读取 IP 列表,依次调用 host.create 接口。每次创建完成后做一次连通性检查,记录成功和失败的主机,失败的主机后续单独重试。接口调用本身不复杂,重点是幂等处理:如果一台机器已经创建过,再调用 host.create 会报错,脚本里要先把已存在的主机查出来过滤掉。
#!/bin/bash for ip in 192.168.10.21 192.168.10.22 192.168.10.23; do echo "Creating host for $ip" # curl host.create ... done9. 资源占用与性能观察
Zabbix Agent 本身资源占用很低,内存通常在几十 MB 量级,CPU 占用可以忽略。Nginx 状态页采集是按固定间隔拉取文本,对 Nginx 业务几乎无影响。整体上这套监控方案的资源开销不会成为瓶颈,真正的瓶颈反而在 Zabbix Server 端的数据库写入。
观察性能时关注三个点:
- 采集频率。默认模板可能是 1m 或 10s,频率越高,Server 端数据库写入压力越大。如果只是看趋势,1m 足够。
- 状态页脚本执行耗时。脚本里用 curl 拉取状态页,正常情况下 ms 级完成;如果状态页返回慢,会影响 Agent 采集间隔,导致数据延迟。
- Server 端在线主机数。当主机数量多时,建索引、分区和历史清理策略要提前规划。
另外,如果 Nginx 机器本身内存紧张,也要控制 Agent 日志级别。默认 info 级别即可,不要长期开 debug,否则 /var/log/zabbix/zabbix_agentd.log 会迅速膨胀。
10. 常见问题与排查方法
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| curl 状态页无输出 | Nginx 没开 stub_status 或没 reload | 检查 nginx -V 输出和 nginx 错误日志 | 编译开启模块或重新加载配置 |
| 状态页返回 403 | allow/deny 顺序问题 | 检查 location 中 IP 是否匹配 | 调整为 allow 127.0.0.1; deny all; |
| Agent 启动失败 | 配置文件语法错误 | systemctl status zabbix-agent 查看日志 | 修正 /etc/zabbix/zabbix_agentd.conf |
| Server 端显示主机不可达 | 端口未通或 Hostname 不一致 | telnet 10050、对比 Hostname | 放通防火墙端口,统一 Hostname |
| 已绑定模板但无数据 | UserParameter 未生效或脚本无执行权限 | zabbix_agent2 -t nginx.status[active] | 给脚本加执行权限并重启 Agent |
| 克隆机数据串到模板机上 | 克隆后 Agent Hostname 没改 | 检查两台机器的 Hostname 配置 | 改为各自唯一 Hostname 并重启 Agent |
| 数据有延迟 | 采集频率、网络抖动、Server 性能 | 看 Latest data 更新时间 | 降低采集频率或优化 Server 查询 |
| 模板找不到 | 模板库未导入 | 检查模板导入记录 | 从官方 Git 下载 XML 导入 |
有几个坑值得单独强调。一个是克隆机器后,Agent 的 Hostname 和 Server 端的主机名必须一致,多一个空格都不行。另一个是 UserParameter 脚本如果用了非 root 用户运行,脚本路径和 curl 命令要保证该用户可访问,特别是 /usr/local/bin 目录权限异常时会返回空值。再一个是修改 Nginx 配置后忘记 nginx -s reload,导致状态页一直不生效。
11. 最佳实践与使用建议
第一,模板机要维护好。把 Nginx 状态页配置、Zabbix Agent 安装、UserParameter 脚本都纳入到模板机的初始化文档里,以后再克隆就不用从头排查。模板机建议定期打快照,但克隆前一定要关闭或确认数据库类服务已停止,避免数据文件不一致。
第二,状态页访问权限要严格限制。只监听 127.0.0.1,由 Zabbix Agent 本机采集是最省心的方案。如果必须远程采集,也要通过 allow 只放开 Zabbix Server 的 IP。
第三,监控指标要筛选。模板里包含的项目不一定全部需要,建议只保留 active、accepts、handled、requests、reading、writing、waiting 这几个核心指标,并配置 triggers。比如 Active connections 超过阈值、requests 5 分钟不增长等告警,真正有用的是告警而不是一大堆图表。
第四,告警要分级。连接数暴增可能是流量高峰,也可能是被刷;Reading 长时间上涨可能是有慢客户端。建议把网络层、Nginx 层、后端服务层的告警分开,避免一个 Nginx 抖动引发全链路告警轰炸。
第五,接口脚本要记录日志。用 API 批量创建主机时,每次调用应该输出返回结果和状态码。Zabbix API 的错误信息比较明确,比如 host already exists 说明这台机器之前已注册;invalid params 说明 templateid 或 groupid 处有问题。
12. 总结与下一步
这套 Zabbix 监控 Nginx 的方案,核心链路就三步:Nginx 开状态页,Agent 用 UserParameter 取数据,Server 端绑模板看曲线。最容易踩的坑集中在克隆机场景:Hostname 冲突、IP 冲突、状态页没生效、Agent 拿不到数据。
建议第一个验证的动作,是在模板机上把 4.2 节的 curl 状态页和 5.3 节的 zabbix_agent2 -t nginx.status[active] 都跑通,这两个命令能通,后面所有问题都好查。然后再去克隆机器,克隆完按 6.2 节改主机名、改 IP、改 Agent Hostname,最后在 Server 端“Latest data”里看数据是否出现。
下一步可以扩展的方向包括:接入 nginx-module-vts 获取更细的 QPS 和响应码数据、把 Nginx 监控和对后端服务的 HTTP 探测组合成一套完整链路监控、用 Zabbix API 对接内部的发布系统实现新机器自动纳管。先把基础监控跑稳定,再逐步加指标和告警,是比较稳妥的推进方式。