网卡软中断不均导致业务进程卡顿,本质是net_rx软中断集中于少数cpu核,挤占业务cpu时间;需通过三组命令验证分布、占比与硬中断源头,再启用多队列、绑定亲和性、开启rps并绑定进程cpu。

网卡软中断不均导致个别工作进程轮询卡顿,本质是网络数据包处理被“钉死”在少数 CPU 核上,造成 NET_RX 软中断集中爆发,挤占了本该用于业务进程(如 Nginx worker、Codis server、MySQL 线程等)的 CPU 时间。此时进程看似在“轮询”,实则是频繁被高优先级软中断抢占、唤醒延迟、上下文切换激增,响应变慢甚至超时。
确认是否真是软中断瓶颈
别急着调配置,先用三组命令交叉验证:
-
观察软中断分布:运行
watch -n 1 'cat /proc/softirqs | grep NET_RX',看各 CPU 列数值增长是否严重失衡(例如 CPU2 比 CPU0 高 4 倍以上) -
检查软中断 CPU 占比:用
top按 1 显示各核,关注 si% 列——若某核长期 >20%,且 %idle 极低,就是明确信号 -
排查硬中断源头:执行
cat /proc/interrupts | grep eth,确认对应网卡的硬中断(如eth0-rx-0)是否也只打在同一个 CPU 上;如果是,说明底层队列没打开或多队列未启用
启用网卡多队列并绑定中断亲和性
单队列网卡天生无法分流,必须升级为多队列模式,并让每个 RX 队列固定由一个 CPU 处理:
- 查支持能力:
ethtool -l eth0看 Combined max 值(如为 8,代表最多 8 队列) - 启用队列:
ethtool -L eth0 combined 8 - 绑定硬中断:
echo 0 > /proc/irq/$(grep "eth0-rx-0" /proc/interrupts | awk '{print $1}' | tr -d ':')/smp_affinity_list(依此类推,把 rx-0→CPU0、rx-1→CPU1…一一对应) - 关闭 irqbalance:
systemctl stop irqbalance,避免它自动干扰手动绑定
开启 RPS 并配合进程 CPU 绑定
多队列解决硬中断,RPS 解决软中断分发;但光分散软中断还不够,Nginx 或其他服务进程得“就近”处理:
- 开启 RPS:
echo ffff > /sys/class/net/eth0/queues/rx-0/rps_cpus(十六进制掩码按实际 CPU 数调整,8 核用ff) - 设置 RPS 流表大小:
echo 4096 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt - Nginx 示例绑定:
worker_processes 8;+worker_cpu_affinity 00000001 00000010 ... 10000000;(每位对应一个 CPU,确保每个 worker 独占一核) - 提升调度权重:
worker_priority -20;,减少被软中断抢占的概率
验证与持续盯控
优化后不是一劳永逸,要闭环验证效果:
- 再次运行
watch -n 1 'cat /proc/softirqs | grep NET_RX',各 CPU 的增长速率应基本一致 - 用
pidstat -w 1查看目标进程的 cswch/s(每秒上下文切换),下降 30% 以上说明软中断干扰显著缓解 - 接入 Prometheus + Grafana,长期跟踪 si% per CPU、NET_RX count delta 和 应用 P95 延迟 三者联动趋势,及时发现偏移











