active connections是nginx应用层真实并发连接数,包含reading、writing、waiting状态,不依赖系统工具且不受time-wait/close_wait干扰;ss统计的established仅反映tcp层连接状态,二者视角不同,偏差超10%需检查keepalive_timeout等配置。

直接看 stub_status 返回的 Active connections 数值
这是最贴近 Nginx 应用层真实并发连接数的方式,Active connections 指当前正在被 worker 处理的连接(含 reading、writing、waiting 状态),不是单纯 TCP ESTABLISHED。它不依赖系统工具,也不受 TIME-WAIT 或 CLOSE_WAIT 干扰。
前提是你已启用 stub_status 模块并配置好 location:
-
nginx -V 2>&1 | grep -o with-http_stub_status_module必须有输出,否则需重编译或换包(如nginx-extras) - 配置中必须包含
stub_status on;,且allow规则允许你访问(本地调试建议allow 127.0.0.1; deny all;) - 执行
nginx -t && nginx -s reload后,用curl http://127.0.0.1/nginx_status查看,首行就是Active connections: 142
用 ss 统计 ESTABLISHED + READING/WRITING 对应的 socket
ss 是内核态统计,快、轻量、现代系统默认自带。但它只看到 TCP 层状态,和 stub_status 的 Active connections 不完全等价 —— 后者还包含已建立但尚未读取请求头的连接(即 reading 状态),而 ss 把这类连接仍归为 ESTABLISHED。
所以更合理的对比方式是:
-
sudo ss -tn state established '( dport = :80 or dport = :443 )' | wc -l→ 得到粗略活跃连接下限 - 若该值比
stub_status的Active connections小很多(比如差 50+),说明大量连接卡在reading,可能是客户端发包慢、TLS 握手延迟、或client_header_timeout设置过长 - 若该值远大于
Active connections(比如 2 倍以上),要警惕后端响应慢、upstream 超时未释放、或 worker 进程卡死没及时 close socket
别用 netstat -an | grep :80 | wc -l 直接当 Active Connections
这条命令会把所有与 80 端口有关的 socket 都算进去:LISTEN、TIME-WAIT、CLOSE-WAIT、SYN-RECV……甚至其他服务(如 httpd)监听 80 的连接也会混入。结果严重失真,尤其高并发时误差可达数百。
真正有用的写法只有两种:
- 按状态过滤:
netstat -an | awk '$6 == "ESTABLISHED" && $4 ~ ":80$" {++i} END {print i+0}' - 但更推荐直接换
ss,因为netstat在 CentOS 8+/Ubuntu 20.04+ 默认不装,且性能差、解析慢,容易在连接数上万时卡住命令本身
注意 stub_status 和 ss 的差异点常被忽略
很多人拿 curl /nginx_status 和 ss -tn state established 对比后发现数字不一致,就认为“监控不准”。其实这不是 bug,而是视角不同:
-
stub_status的Active connections是 Nginx worker 主动维护的连接生命周期计数,包含 waiting(keepalive 空闲连接)、reading(等待请求头)、writing(发送响应中) -
ss的ESTABLISHED只反映 TCP 连接是否建好,不管应用层有没有开始处理;TIME-WAIT和CLOSE-WAIT则完全不在stub_status统计范围内 - 真正该交叉验证的是:
stub_status的Active≈ss的ESTABLISHED+ 当前worker_connections中处于reading/writing的数量(后者需查nginx -T看配置)
如果两者长期偏差超过 10%,优先检查 keepalive_timeout、client_header_timeout 和 upstream health check 是否异常。











