当nginx在极高吞吐下出现cpu飙升、延迟抖动、worker进程不均且mpstat显示si%超60%,根源是网卡中断分布不均导致软中断过载;需通过/proc/interrupts检查中断倾斜,用smp_affinity_list绑定中断到多核,启用rps,并配置worker_cpu_affinity实现nginx与中断的cpu协同隔离。

当 Nginx 在极高吞吐(如 QPS > 20k)下出现 CPU 使用率飙升、响应延迟抖动大、部分 worker 进程几乎不工作,而 top 中看不到明显高 CPU 应用进程,且 mpstat 显示某几个 CPU 核心的 si(软中断)占比长期超 60%,大概率是系统中断处理不均引发的 CPU 瓶颈——这不是 Nginx 配置问题,而是内核调度与网卡中断绑定失衡所致。
看中断分布是否倾斜
执行命令查看各 CPU 核心处理的中断情况:
-
cat /proc/interrupts | grep -E "(eth|enp|bond)"—— 找出网卡相关中断号(如 45、46、47) - 观察每列数字(对应 CPU0、CPU1…),若某几列数值远高于其他列(比如 CPU3 处理了 95% 的 rx/tx 中断),说明中断集中在一个或少数核心上
- 特别注意
NET_RX和IRQ_POLL类中断,它们直接关联网络包接收与软中断处理
确认软中断是否过载
运行以下命令验证软中断是否成为瓶颈:
-
mpstat -P ALL 1 3—— 观察每秒输出中 si% 列,若单核持续 > 50%,且该核的 %usr 很低( -
cat /proc/softirqs—— 查看 NET_RX 和 NET_TX 行累计值,对比前后 10 秒差值;若每秒增长数百万次,说明网络包洪峰已超出单核软中断处理能力
强制均衡中断亲和性
Linux 默认不会自动均衡网卡中断,需手动绑定到多个 CPU:
- 先查当前中断亲和掩码:
cat /proc/irq/45/smp_affinity_list(45 是中断号) - 将中断分散到 CPU0–CPU7(假设是 8 核):
echo "0-7" > /proc/irq/45/smp_affinity_list - 对每个网卡中断号重复操作(可用脚本批量处理);注意:该设置重启失效,需写入启动脚本或 systemd service
- 推荐搭配 RPS(Receive Packet Steering)启用:
echo 3fff > /sys/class/net/eth0/queues/rx-0/rps_cpus(十六进制位图,覆盖前 12 个 CPU)
配合 Nginx 做 CPU 绑定隔离
避免 Nginx worker 与中断处理竞争同一核心:
- 在
nginx.conf中启用 CPU 亲和:worker_cpu_affinity auto;(Nginx 1.21+ 支持)或手动指定:worker_cpu_affinity 0001 0010 0100 1000; - 确保 Nginx worker 分配的 CPU 与网卡中断绑定的 CPU 有重叠但不完全重合(例如中断绑 CPU0–3,Nginx 绑 CPU2–7),留出专用核做软中断,其余核专注处理请求
- 关闭非必要服务(如 cron、auditd)在关键 CPU 上运行,减少干扰
不复杂但容易忽略:中断不均不会报错,只会让 Nginx 表现为“CPU 高却没干活”,排查时别只盯着 nginx 进程本身。











