multi_accept on 配合 use epoll 可使 worker 在单次事件循环中批量 accept 所有就绪连接,显著减少系统调用与上下文切换,在代理场景下尤其能降低短连接洪峰(如秒杀、健康检查)引发的握手延迟和 listen overflow。

开启 multi_accept on 并搭配 use epoll,能显著减少高并发下连接建立的系统开销,尤其在代理场景中缩短客户端与后端服务之间的握手延迟。
为什么 multi_accept 对代理场景特别重要
反向代理常面临短连接密集、健康检查集中、爬虫探测或秒杀类突发流量。此时 listen 队列可能堆积多个已完成三次握手的连接。默认 multi_accept off 时,每个 worker 每次只取一个连接,频繁进出事件循环,造成:
- 多余的
accept()系统调用,消耗 CPU - 连接就绪但未及时处理,增加首包延迟(TTFB)
- 在多 worker 场景下,若
accept_mutex开启,还可能加剧锁竞争
必须满足的生效前提
multi_accept 不是“一开就灵”,它依赖底层事件模型和运行环境:
- 仅在
use epoll(Linux)或use kqueue(FreeBSD)下有效;select/poll下完全不生效 - Linux 内核需 ≥2.6,且启用
net.core.somaxconn(建议 ≥65535)以避免 listen overflow - 需配合足够大的
worker_connections(如 16384 或更高),否则新连接会被丢弃 - 不建议关闭
accept_mutex,除非已压测验证无惊群问题且使用了 SO_REUSEPORT
推荐配置写法与验证方式
在 nginx.conf 的 events 块中明确声明:
use epoll;
multi_accept on;
worker_connections 16384;
}
上线后通过以下方式确认是否生效:
- 检查 Nginx 启动日志:出现
using epoll, multi_accept is enabled - 运行
ss -lnt | grep :80观察Recv-Q是否长期接近 0(说明连接被快速清空) - 压测时对比
netstat -s | grep -i "listen overflows":开启后该计数应趋近于 0 - 用
perf stat -e syscalls:sys_enter_accept对比单位时间 accept 系统调用次数,下降 30%+ 属正常
代理链路中的协同优化点
单开 multi_accept 效果有限,需同步调整代理行为:
- 设置
proxy_connect_timeout 3s和proxy_read_timeout 15s,避免长阻塞拖慢连接池复用 - 启用
proxy_buffering on+ 合理的proxy_buffers,减少上游响应等待对连接状态的影响 - 若代理 HTTPS 后端,确保
ssl_protocols TLSv1.2 TLSv1.3,避免 TLS 握手耗时掩盖网络层优化收益 - 对健康检查接口(如
/healthz),单独配置proxy_http_version 1.1和Connection: close,防止短连接干扰主流量队列











