nginx-vts模块未生效导致/status返回404,需确认是否编译进nginx(nginx -v | grep nginx-vts)、http块中配置vhost_traffic_status_zone、且location /status置于含server_name的server块内;数据按server_name自动分组,正则或通配符server_name不被识别;json为空需检查vhost_traffic_status_display on及过滤指令;安全上须用allow/deny限制ip,禁用auth_basic。

nginx-vts 模块没生效,/status 返回 404 怎么办
Nginx 编译时没加 nginx-vts 模块,或者配置漏了 vhost_traffic_status_zone,/status 路径就根本不会被识别。这不是 reload 配置能解决的,得重编译或换预编译包。
- 确认模块已加载:
nginx -V 2>&1 | grep -o nginx-vts,无输出说明没编译进去 - 必须在
http块里加:vhost_traffic_status_zone;(不带参数即可,但不能省) -
location /status块必须放在某个server下,且该server不能是纯反向代理(即得有实际监听和域名) - 如果用了
include分离配置,检查是否漏掉了含vhost_traffic_status_zone的文件
怎么让每个虚拟主机的流量单独显示,而不是全站汇总
默认开启 vhost_traffic_status_zone 后,数据按 server_name 自动拆分,但前提是每个 server 块都显式写了 server<em>name</em>,且不能全是 或空。
-
server_name example.com www.example.com;→ 这样会归到example.com下,www不单独计 -
server_name ~^www.(.+)$;→ 正则匹配的server_name不会被 vts 识别为独立 host,流量会进default - 如果多个
server共用一个端口又没设server_name,所有请求都会算进default虚拟主机 - 想看通配符子域(如
*.api.example.com),得用map提前提取主域再赋给变量,vts 本身不解析通配逻辑
/status/format/json 返回空或字段缺失
vts 的 JSON 接口默认只返回启用的统计维度。如果没开连接或缓存相关指令,对应字段就是空的,不是 bug。
-
vhost_traffic_status_display必须设为on(它控制整个状态页开关,不只是 HTML) - 想看到
in_bytes、out_bytes,确保没加vhost_traffic_status_filter_by_host off;(这个关掉后 host 维度会失效) - 如果用了
proxy_cache,但没配vhost_traffic_status_filter_by_set_key,缓存命中请求的出流量可能远低于实际(因为响应从本地发,不走 upstream) - JSON 中的
connections是瞬时值,不是累计;而request_counter是累计,重启 Nginx 会清零
监控页面被刷爆或暴露在公网的风险怎么控
/status 默认没鉴权,谁都能访问,而且每秒刷新一次会拖慢 worker 进程,尤其高并发时。
- 用
allow/deny锁 IP:allow 127.0.0.1; deny all;,别只靠防火墙 - 不要用
auth_basic,vts 的 status 接口不支持,加了也无效,只会返回 404 或空白 - 如果必须外网看,走反向代理加 JWT 验证,或把
/status改成带随机路径(如/status-8a3f2e),并定期轮换 - 高频轮询(nginx -t 日志里有没有
shm zone "vhost_traffic_status" is busy
vts 的数据精度依赖于 shared memory zone 刷新频率,不是实时毫秒级的,而是按事件驱动聚合——这意味着短时突发流量可能被平滑,别拿它当 tcpdump 用。











