核心在于均匀分散net_rx软中断:先用watch和top确认单核瓶颈,再启用网卡多队列(ethtool -l eth0 combined n)、配置rps(echo掩码>rps_cpus),并严格绑定nginx worker与cpu(worker_processes n + worker_cpu_affinity)。

处理 Nginx 大规模并发时的内核中断开销,核心在于让网络数据从网卡进来的第一刻起,就均匀分散到多个 CPU,避免单核被 NET_RX 软中断打满。这不是调 Nginx 配置能解决的问题,而是要打通“网卡→中断→软中断→worker 进程”的整条链路。
确认是否真存在软中断瓶颈
先验证问题是否存在,再动手优化:
- 运行
watch -n 1 'cat /proc/softirqs | grep NET_RX',观察各 CPU 列数值增长是否严重不均(例如某 CPU 是其他核的 3–5 倍) - 同时看
top中对应 CPU 的si%(softirq 占比),持续高于 15% 就是明显瓶颈 - 再执行
cat /proc/interrupts | grep eth,检查硬中断(如IR-PCI-MSI)是否也集中在同一 CPU——若如此,说明网卡多队列未启用
启用网卡多队列并开启 RPS
单队列网卡天然会把所有流量压向一个 CPU,必须升级为多队列模式:
- 查支持队列数:
ethtool -l eth0(例如显示Combined: 8,即最多 8 队列) - 启用 8 队列:
ethtool -L eth0 combined 8 - 设置 RPS 分发软中断:
echo ffff > /sys/class/net/eth0/queues/rx-0/rps_cpus(16 核用ffff;8 核用ff,按需调整位掩码) - 确保
/sys/class/net/eth0/queues/下出现rx-0到rx-7共 8 个接收队列目录
绑定 Nginx worker 与 CPU 严格对齐
软中断分开了,但若 Nginx worker 还在随机调度,跨核缓存失效会抵消优化效果:
- 显式设
worker_processes 8;(匹配队列数和物理核数) - 用
worker_cpu_affinity一对一绑定:worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000; - 可加
worker_priority -20;提升调度权重,减少被抢占概率
配套验证与长期监控
优化后必须验证是否真正生效:
- 重启 Nginx 并重载网卡驱动(或重启服务器),再次运行
watch -n 1 'cat /proc/softirqs | grep NET_RX',各 CPU 增长速率应基本一致 - 用
pidstat -w 1观察 Nginx worker 的上下文切换次数(cswch/s),下降明显说明唤醒压力减轻 - 建议将
si%、每 CPU 的NET_RX计数、Nginx P95 延迟三项指标接入 Prometheus + Grafana,形成性能闭环











