Nginx异步事件驱动机制不实现集中式任务队列,其“排队”是分层隐式的:内核TCP listen backlog暂存未accept连接,worker通过epoll_wait调度就绪连接,proxy_buffering控制响应缓冲,upstream keepalive复用连接减少建连阻塞。

内核 listen backlog 是第一道排队入口
当客户端发起 SYN,而 Nginx worker 还没来得及 accept 时,连接由内核暂存。这个队列长度由 listen ... backlog=xxx 指令控制(默认 511)。超过该值,新 SYN 直接被丢弃(SYN DROP),客户端看到超时或连接拒绝。
- backlog 不是 Nginx 自己维护的,而是通过
listen()系统调用传给内核的参数 - 它只管“三次握手完成但尚未被 accept”的连接,不涉及 HTTP 请求内容
- 调大需同步调整系统参数:
net.core.somaxconn,否则会被截断
worker 进程内:连接就绪但未处理,靠 epoll_wait 等待调度
Nginx worker 用 epoll 监听所有 socket。当某个 client socket 变成 EPOLLIN 就绪态,说明有数据可读(如请求头到达),但它未必立刻被处理——要等当前事件循环轮到它。
- epoll_wait 返回一批就绪 fd,Nginx 按顺序遍历处理;若并发高,靠后的连接会略微延迟进入读流程
- 这种“排队”是瞬时的、无状态的,发生在事件分发层,不占内存缓冲
- 启用 multi_accept on 可让单次 epoll_wait 后尽可能多地 accept 新连接,减少排队深度
HTTP 请求体和响应阶段:proxy_buffering 控制是否积压
这是最容易被误认为“任务排队”的地方。当 proxy_buffering on(默认)时,Nginx 会等后端返回完整响应,再统一转发给客户端。如果后端慢,响应数据就在 Nginx 内存中暂存——这相当于人为制造了一个“中间缓冲队列”。
- 关闭它:proxy_buffering off,Nginx 收到一点就发一点,消除响应侧排队
- 开启时,用 proxy_buffer_size 和 proxy_buffers 控制缓冲区大小,避免小缓冲导致频繁刷写和假性排队
- 注意:缓冲不是为“排队”设计的,而是为性能与协议兼容性服务的
后端通信层:upstream keepalive 减少连接重建排队
如果 upstream 没配 keepalive,每个请求都要新建 TCP 连接。建连耗时、TIME_WAIT 占用、后端连接数上限都会导致请求在 upstream 阶段卡住——看起来像在排队,实则是连接资源不足。
- 配置 keepalive 32,让每个 worker 复用最多 32 个空闲长连接
- 搭配 proxy_http_version 1.1 和 proxy_set_header Connection '',确保复用生效
- 设置合理的 proxy_connect_timeout 和 proxy_next_upstream,避免单个失败请求阻塞整个连接槽位



















