
图中连接状态是某一时刻的数量,请求计数则要结合时间差才能计算平均速率。
看到 Nginx 状态页显示几十个连接,能不能说当前每秒正在处理几十个请求?不能。连接、请求和速率是不同对象,瞬时状态与启动以来的累计值也不能混算。stub_status 的字段不多,真正的考点是每一项究竟在数什么。
先看当前连接的四个字段
Active connections 描述当前活动客户端连接数,其中包括空闲等待后续请求的连接。Reading 是正在读取请求头的连接数;Writing 是相应请求处理和响应写出阶段的连接数;Waiting 是保持连接、等待下一个请求的空闲连接数。
因此,Active 不等于当前正在消耗大量 CPU 的请求数,Waiting 也不代表这些连接正在排队等待上游处理。把“空闲 keep-alive 等下一次请求”解释成“服务忙不过来的等待队列”,就会把健康的连接复用误读成拥塞。
在一致的同一时刻口径下,可以用状态分类关系理解 Active 与后三项之和。但读取监测值本身存在采样时序,不要把高频变化下的一次数值差异直接判为服务故障。先确认字段、采样方式和实际环境。
Writing 不等于只在执行写系统调用
名称很容易让人联想到线程正忙着把字节写入网卡,但连接可以在处理响应的过程中经历等待等状态。不能仅凭 Writing 很高,就断定瓶颈一定是网络发送;上游耗时、客户端读取速度和响应大小,都可能影响连接驻留。
例如上游处理变慢,许多连接长时间留在相关阶段,数量会增加;另一个场景是客户端接收很慢,响应也可能长时间无法完成。两种情况的连接状态看起来接近,定位证据却不同,需要结合请求耗时和上游指标区分。

三个大数字是累计计数
状态页还会显示 accepts、handled、requests,分别对应累计接受的客户端连接、累计处理的连接与累计处理的客户端请求。它们不是当前并发量,也不是已经按秒换算的速率。
通常 accepted 与 handled 接近;若两者出现差异,可以结合资源限制与错误日志继续排查,但单凭一个差值不能证明唯一原因。requests 可以明显大于连接数,因为一个连接能够承载多个请求;反过来,一个连接被建立,也不保证已经形成一个完整的业务请求。
HTTP 协议的连接复用还会改变连接与请求的对应关系,尤其不能在允许多路复用的场景下,把连接数一比一换算成并发请求数。字段统计对象不变,但业务解释需要协议上下文。
用两个采样点算速率
自设一个例子:请求累计计数在十秒内从一千变为一千一百二十,差值是一百二十,这个窗口内请求计数的平均增长速率就是每秒十二。它与某一瞬间 Writing 恰好为八或二十,没有直接相等关系。
这个平均值也不等于每一秒都稳定为十二,更不应直接当作成功业务请求的完成速率。若你要成功率、响应状态分布或端到端延迟,需要访问日志或更合适的监测数据;一个总计数没有携带这些细节。
计算差值前,还要检查进程或采集目标是否重启、计数是否重置,以及两个样本是否来自同一个实例。差值变成负数时,不应继续生成一个负 QPS,而应标记这段窗口不可按原口径比较。
连接多不一定需要扩容
假设某个时刻 Active 为四十,Reading 为二,Writing 为八,Waiting 为三十。多数连接正在空闲复用,并不能由四十这个数字直接推出服务器负载很高。应该同时观察资源利用、实际流量、请求耗时和错误。
同样,Waiting 很少也不天然更好。客户端不复用连接、频繁重连,可能让空闲连接少却增加建立成本。好的诊断需要说明业务模式,不是把每个数字越小越好当成目标。
把状态页当作线索入口
模块是否可用要看实际构建与配置,状态访问路径也应有明确的访问范围。排查时保存同一实例的一段连续样本,再关联其他日志,远比截一张状态页就下结论可靠。
面试回答可以分为“当前状态、累计计数、时间差速率、额外诊断证据”四层。若 Waiting 一直很高,但请求延迟和资源指标都稳定,你会先判定拥塞,还是先核对连接复用模式?