reuseport 通过内核哈希分发连接,彻底绕过互斥锁,每个 worker 拥有独立 listen socket,按四元组哈希仅唤醒对应进程 accept,实现无锁无争抢的多核负载均衡。

listen ... reuseport 指令并不开启内核级互斥锁,恰恰相反——它的核心价值是彻底绕过互斥锁,用内核哈希分发代替用户态锁竞争。
所谓“内核级互斥锁”是常见误解。Linux 内核中没有名为“reuseport 互斥锁”的机制;SO_REUSEPORT 是一个 socket 选项,启用后让多个独立 socket 绑定同一端口,由内核在连接建立阶段(SYN 收到时)直接按四元组哈希,仅唤醒对应 worker 的 accept 队列,其余 worker 完全不参与该连接的调度。这是一种无锁、无唤醒、无争抢的分发模型。
要实现多 worker 间的极致流量均衡,关键不是加锁,而是让每个 worker 拥有真正独立的监听入口,并确保内核和 Nginx 协同工作:
必须统一启用,不能混用
同一 IP:Port 组合的所有 listen 行(包括 IPv4 和 IPv6)都必须带 reuseport,否则 Nginx 配置校验失败:
- ✅ 正确:
listen 80 reuseport; listen [::]:80 reuseport; listen 443 ssl reuseport; listen [::]:443 ssl reuseport;
- ❌ 错误:只给 IPv4 加、IPv6 不加,或部分 server 块漏写,会导致启动报错。
关闭 accept_mutex,释放用户态锁开销reuseport 已从内核层解决惊群,再保留 accept_mutex on 反而引入额外锁竞争:
- 确保 events 块中未设置
accept_mutex on - 显式关闭更稳妥:
accept_mutex off; -
multi_accept on;在此场景下不再必要,可省略
绑定真实硬件资源,提升缓存局部性
仅靠哈希分发还不够,需让连接处理路径贴近物理资源:
- 设置
worker_processes auto;或明确为 CPU 物理核心数 - 启用
worker_cpu_affinity auto;,使每个 worker 固定运行在独立核心 - 若服务器支持多队列网卡,开启 RPS/RFS 并对齐 worker 分布,减少跨 NUMA 访存
扩大内核连接队列,避免隐性丢包
reuseport 分发再均衡,若底层队列太小,连接仍会堆积或被丢弃:
- 调大全连接队列:
net.core.somaxconn = 65535 - 调大半连接队列:
net.ipv4.tcp_max_syn_backlog = 65535 - Nginx listen 中建议显式追加
backlog=65535:listen 80 reuseport backlog=65535;
验证是否真正生效,看三处:
-
ss -tlnp | grep :80输出应显示多行,每行 PID 对应一个 worker 进程 -
ps aux | grep 'nginx: worker'进程数与worker_processes一致 - 压测时
top -H -p $(pgrep nginx)中各 worker 线程 CPU 使用率相对均衡,无单核长期 100%
不复杂但容易忽略

















