要让nginx网络i/o真正跑满多核能力,必须使worker进程与网卡rss队列严格对齐:先启用多队列并绑定rx中断到指定cpu,再通过worker_cpu_affinity将worker绑定至对应核心,配合accept_mutex off和multi_accept on实现“谁收包、谁处理”,避免跨核数据搬运。

要让 Nginx 的网络 I/O 真正跑满多核能力,光设 worker_processes auto 不够。核心在于让每个 worker 进程“就近处理”它对应网卡队列收上来的包——中断在哪颗 CPU 上发生,就由绑定在同一颗 CPU 的 worker 来完成后续解析、转发和响应,避免跨核搬运数据、缓存失效和延迟飙升。
确认并启用网卡多队列(RSS)
这是硬件层前提,Nginx 无法驱动它,必须先配好:
- 查当前队列数:
ethtool -l eth0,看 Current hardware settings 下 RX/TX channel 是否 ≥ 2 - 若不足,启用多队列(建议值 = 物理 CPU 核数):
sudo ethtool -L eth0 combined 4 - 验证生成:
ls /sys/class/net/eth0/queues/应出现rx-0、rx-1等子目录
将 RX 中断精准绑定到物理 CPU
每个 rx-N 队列对应一个独立中断号,不手动绑定,默认全落在 CPU 0:
- 查中断映射:
grep "eth0-rx" /proc/interrupts,找到类似45: eth0-rx-0 - 按队列轮询绑定(以 4 队列为例):
echo 1 > /proc/irq/45/smp_affinity_list(rx-0 → CPU0)echo 2 > /proc/irq/46/smp_affinity_list(rx-1 → CPU1)echo 4 > /proc/irq/47/smp_affinity_list(rx-2 → CPU2)echo 8 > /proc/irq/48/smp_affinity_list(rx-3 → CPU3) - 若为 NUMA 架构,用
lscpu查节点拓扑,优先把同一节点内的 CPU 分配给一组队列
让 Nginx worker 与 RSS 队列严格对齐
目标是“谁收包、谁处理”,减少软中断与 worker 之间的跨核拷贝:
- 设
worker_processes 4(匹配队列数),并显式绑定:worker_cpu_affinity 0001 0010 0100 1000; - 更推荐自动模式(Nginx ≥ 1.9.10):
worker_processes auto;worker_cpu_affinity auto;
它会感知 NUMA 节点,并将 worker 均匀分到各本地节点的连续物理核心上 - 验证是否生效:
ps -eo pid,psr,comm | grep nginx,观察各 worker 的 CPU 编号是否与前面 RX 中断绑定的 CPU 一致
补足软中断与连接调度协同
硬中断分散后,软中断(ksoftirqd)和 accept 锁仍可能成为瓶颈:
- 开启 RPS(软件层面再均衡,适用于无 RSS 或 RSS 不足场景):
for i in /sys/class/net/eth0/queues/rx-*/rps_cpus; do echo f > $i; done
(f = 0xf = CPU0–3,按实际 CPU 掩码调整) - 关闭 accept 锁:
accept_mutex off;(Nginx ≥ 1.11.3 默认已关) - 启用一次多连:
multi_accept on;,降低事件循环压力,提升单次事件处理吞吐











