multi_accept on 的作用是让每个 worker 进程在单次事件就绪后持续调用 accept() 直至内核 listen 队列为空,从而批量收取已建立连接;它必须配合 use epoll、足够大的 somaxconn 与 backlog、匹配的 worker_connections 及 reuseport 等协同配置才生效。

multi_accept on 并不是让 Nginx “一次接收多个连接”,而是让每个 worker 进程在单次事件就绪后,尽可能多地调用 accept() 系统调用,把内核 listen 队列里所有已建立(ESTABLISHED)的连接一次性取完。它不改变 TCP 握手流程,也不突破连接数上限,但能显著减少事件循环次数和系统调用开销——尤其在突发短连接场景下效果明显。
必须放在 events 块中,且顺序关键
配置必须写在 events { ... } 内,且 use epoll;(Linux)或 use kqueue;(FreeBSD/macOS)要放在 multi_accept on; 之前:
events {
use epoll;
multi_accept on;
worker_connections 8192;
accept_mutex off;
}-
use epoll;不可省略或依赖自动探测,select/poll下multi_accept完全无效 -
worker_connections要足够大(如 8192、16384),否则批量 accept 时超出限制会失败并返回错误 -
accept_mutex off在高并发短连接场景下更推荐:避免多个 worker 因争抢 accept 锁而排队,让每个 worker 独立、无锁地消费连接队列
光配 nginx 不够,内核参数也得跟上
multi_accept 要起效,前提是内核 listen 队列里真有多个就绪连接。否则“想多取,但没得取”。需同步调整:
-
net.core.somaxconn=65535:扩大全连接队列上限(已三次握手完成的连接) -
net.ipv4.tcp_max_syn_backlog=65535:防止半连接队列(SYN_RECV)溢出丢包 - Nginx 的
listen指令显式加backlog=65535,例如:server { listen 80 backlog=65535; }
注意:
somaxconn和backlog值要一致或后者 ≤ 前者,否则实际生效以较小值为准。
搭配 reuseport 效果翻倍
如果你用的是 Nginx 1.9.1+ + Linux 3.9+,强烈建议在 listen 后加上 reuseport:
server {
listen 80 reuseport backlog=65535;
}-
reuseport让内核在多个 worker 间直接分发新连接,避免单个 listen 队列成为瓶颈 - 它和
multi_accept是互补关系:前者负责“分发”,后者负责“捞取”,两者配合才能真正释放多核性能
怎么确认它真的生效了?
改完配置别急着上线,验证三步走:
- 重启后执行
nginx -t && nginx -s reload,确保加载成功 - 用
strace观察 worker 进程的accept4调用:strace -p $(pgrep nginx | head -1) -e trace=accept4 -f 2>&1 | grep accept4
压测时若看到连续多个
accept4(...)=>fdX在同一毫秒内输出,说明批量 accept 已启动 - 查看内核是否还在丢连接:
netstat -s | grep -i "listen overflows"
数值不再增长,说明 listen 队列没溢出,
multi_accept正在有效清空队列
不复杂但容易忽略:它不是开关一开就提速,而是整套机制协同工作的结果。


















