nginx请求堆积本质是连接层资源耗尽导致的多级被动排队,需分三层定位:内核listen队列、worker连接槽位、上游等待;解决关键在于加速连接接入、合理复用、及时释放,而非扩容队列。

Nginx 本身没有显式的“请求队列”配置项,所谓请求堆积,其实是连接层资源耗尽后,系统在不同层级被动排队的结果。解决的关键不是加队列长度,而是让连接能更快进来、更合理复用、更及时释放,从而避免堆积在入口或 worker 内部。
先搞清堆积发生在哪一层
Nginx 的请求排队是分阶段的:
- 第一层:内核 TCP listen 队列(已完成三次握手但还没被 Nginx accept)
- 第二层:worker 进程的连接槽位(worker_connections 耗尽后新连接无法 accept)
- 第三层:反向代理时上游连接等待(后端慢、复用不足,导致 client connection 卡住)
如果日志出现 worker_connections are not enough 或 accept() failed (24: Too many open files),说明已卡在第二层;若压测时连接直接超时或被拒绝,可能第一层就满了。
确保底层承载能力不成为瓶颈
- 把
net.core.somaxconn设为65535,写入/etc/sysctl.conf并执行sysctl -p -
worker_processes设为 CPU 核心数(推荐auto),worker_connections按业务类型设合理值:短连接 API 可设16384,长轮询或 WebSocket 建议8192~12288 - 同步配齐三重文件描述符限制:
- 系统级:
/etc/security/limits.conf中为 nginx 用户设soft/hard nofile 65536 - 进程级:
nginx.conf主块中加worker_rlimit_nofile 65536 - 验证方式:
cat /proc/$(pgrep nginx)/limits | grep "Max open files"
- 系统级:
让连接进来得更快、分得更匀
-
events块中必须写use epoll;(Linux 下不写会回退到 select/poll 的 1024 硬限) - 开启
multi_accept on;,使单次事件循环尽可能多收连接,缓解突发流量排队 - 负载均衡场景下,把
upstream的调度算法从默认round-robin改为least_conn;,优先把新请求打到当前连接数最少的后端节点
减少连接“占而不放”,尤其针对长轮询
-
keepalive_timeout不要设太高,长轮询建议30~45s,比业务最长等待时间略宽即可 -
keepalive_requests设为2~5,避免一个连接反复复用几十次却长期空闲 - 后端启用
upstream keepalive 32;,并配proxy_http_version 1.1;和proxy_set_header Connection '';,确保连接真正复用 - 对实时性高的接口(如 SSE),可关缓冲:
proxy_buffering off;,响应边收边传,不积压
不复杂但容易忽略











