排查 Nginx 连接池状态时,最直接的方法就是检查 /nginx_status 端点。然而,很多人在配置完成后,满心期待地访问,却只看到 404 或 403 错误,令人困惑。问题通常出在两个地方:一是 Nginx 编译时未包含 ngx_http_stub_status_module 模块,二是配置细节出现遗漏。
验证模块是否已启用,一条命令即可搞定:直接运行 nginx -V 2>&1 | grep -o with-http_stub_status_module。如果有输出,说明模块已就绪;若没有输出,则需要重新编译 Nginx,或更换软件包。例如,在 Ubuntu 下,nginx-full 通常自带该模块,而轻量级的 nginx-light 则不包含。
假设模块确认存在,配置也写好了,但仍然无法访问?那多半是忽略了以下三个细节中的至少一个。
配置 /nginx_status 时最容易忽略的三件事
第一,stub_status on; 这条指令必须放置在 location 块内才能生效。如果写在 server 块或 http 块中,Nginx 会直接忽略。第二,访问控制的 allow 和 deny 指令顺序绝不能颠倒。如果写成 deny all; allow 127.0.0.1;,那么所有请求都会被拒绝,因为 Nginx 会按顺序逐条检查规则。正确的做法是:先写 allow,再写 deny all。第三,检查监听地址是否匹配。很多服务器上运行着多个 server 块,都监听 80 端口。如果你只在其中一个块中配置了 /nginx_status,而你访问的域名恰好命中另一个块,自然就会返回 404。
好,配置搞定后,来看看通过 curl 访问 /nginx_status 返回的信息到底说明了什么。
看懂 status 页面上的几个关键数值
成功访问后,你大概会看到类似下面的输出:
Active connections: 12 server accepts handled requests 123456 123456 234567 Reading: 2 Writing: 5 Waiting: 5
其中,Active connections 表示当前所有活跃的 TCP 连接数——它包括了正在读取请求头的连接、正在写响应的连接,以及处于 keepalive 空闲状态等待新请求的连接,并非单纯的并发请求数。而 accepts 和 handled 这两个数值,分别代表 Nginx 启动以来接受的连接总数和成功处理的连接数。如果两者相等,说明 Nginx 从未拒绝过连接,这是一个不错的信号。
下面三行则更具实时性:Reading 表示 Nginx 正在读取请求头的连接数,Writing 表示正在向客户端发送响应的连接数,而 Waiting 是最容易被忽视的——那些已经处理完请求、仍在 keepalive 中等待下一个请求的空闲连接。这三个数字能直接反映当前连接池的“心跳”节奏。
即使没有 stub_status,也能大致判断压力状况
当然,有些场景下你无法修改配置,或者模块无法安装。这时,系统级命令也能帮你粗略估算压力。例如,使用 ss -ant 'sport = :80' | wc -l 来统计 80 端口上的 ESTABLISHED 连接,速度比 netstat 快得多。也可以更精确地过滤出与 Nginx 相关的连接:ss -ant state established '( sport = :80 or dport = :80 )' | wc -l。
另外,TIME_WAIT 的数量值得特别关注。用 ss -ant state time-wait '( sport = :80 or dport = :80 )' | wc -l 看一眼,如果这个值长期高于 2000,说明短连接过于频繁,就需要考虑调优 keepalive_timeout,或者排查客户端是否存在问题。
这里需要特别说明:ss 统计的是内核级别的 TCP 状态,与 stub_status 中的 Active connections 虽然接近,但并不完全等价。因为 stub_status 还包含了那些处于 keepalive 空闲状态但尚未断开连接,而 ss 仅反映内核中实际的连接状态。
实际上,观察连接池压力时,最重要的不是盯着某个绝对数值,而是关注比例。真正有价值的是 Waiting 占 Active connections 的百分比。如果这个比例长期低于 10%,说明 keepalive 机制基本没有发挥作用,连接用完就断,白白浪费了握手开销。如果长期高于 80%,则问题可能更大——要么是后端响应太慢,导致请求排队;要么是客户端请求过于频繁,使大量连接卡在 Waiting 状态无法释放。这才是需要警惕的信号。

