关键在于用isolcpus启动级隔离cpu核心(如2,3),再配合worker_cpu_affinity精确绑定nginx worker进程,同时禁用irqbalance等干扰服务,缺一不可。

要让 Nginx 在转发场景中获得稳定、低抖动的 CPU 资源,关键不是“让它多用 CPU”,而是“不让其他进程抢它的 CPU”。isolcpus 是实现这一目标的底层基石,它配合 Nginx 自身的亲和性配置,才能真正达成独占效果。单纯改 worker_processes 或加 CPU 绑定,没有隔离,等于在闹市里划条线说“这是我的地盘”——别人照样能进来。
第一步:精准隔离 CPU 核心(启动级隔离)
isolcpus 的作用是让内核调度器“看不见”这些核心,普通进程、中断、软中断、RCU 回调等默认都不会落到上面。这不是建议,是强制排除。
- 编辑 /etc/default/grub,在
GRUB_CMDLINE_LINUX_DEFAULT中加入三要素组合:
isolcpus=2,3 nohz_full=2,3 rcu_nocbs=2,3
说明:
• isolcpus=2,3:CPU 2 和 3 从 CFS 调度器中移除;
• nohz_full=2,3:禁用这两核的周期性 tick,消除时钟中断干扰;
• rcu_nocbs=2,3:把 RCU 回调迁走,避免后台回调偷偷占用 CPU 时间。
- 更新并重启:
sudo update-grub && sudo reboot
- 验证是否生效:
cat /sys/devices/system/cpu/isolated
输出应为 2-3 或 2,3;再检查启动参数:
cat /proc/cmdline | grep isolcpus
第二步:绑定 Nginx worker 到隔离核心(进程级绑定)
隔离只是“清场”,你还得把 Nginx 明确请进这片清净地。靠 worker_cpu_affinity 实现,它比 taskset 更可靠,是 Nginx 主动在 fork worker 时完成的绑定。
- 在 nginx.conf 的
main块中配置(注意:必须在 events 外、http 外):
worker_processes 2;<br>worker_cpu_affinity 00000100 00001000; # 对应 CPU2 和 CPU3(bit 2 和 bit 3,从 0 开始计数)
说明:
• 若系统是 4 核(CPU0–CPU3),二进制 00000100 表示只用第 2 位(即 CPU2);
• 不要用 auto,它无法保证绑定到隔离核;
• 数量必须与 worker_processes 严格一致。
- 重启 Nginx 生效:
sudo nginx -t && sudo systemctl reload nginx
- 验证绑定结果:
ps -eo pid,comm,psr | grep nginx | grep -v master
看到每个 worker 的 psr 列固定为 2 或 3,即成功。
第三步:配套收尾,堵住资源泄漏口
即使 CPU 隔离了,若其他子系统仍往上面扔活,性能优势会打折扣。
-
关闭隔离核上的非必要服务:如
irqbalance(它会主动把中断均衡过去),停用:
sudo systemctl stop irqbalance<br>sudo systemctl disable irqbalance
-
手动绑定关键中断(可选但推荐):查网卡中断号,用
echo $mask > /proc/irq/$N/smp_affinity_list把它引到非隔离核(如 CPU0/CPU1),避免硬中断抢占 Nginx 的时间片。 -
Nginx 自身调优同步做:启用
reuseport分摊 accept 压力,设worker_priority -5提升调度优先级,use epoll+multi_accept on提高事件吞吐。
为什么不能只靠 worker_cpu_affinity?
因为没隔离时,内核仍可能把其他进程、定时任务、ksoftirqd、kswapd 等调度到同一核心上。它们虽不常驻,但一次上下文切换或一次软中断处理,就足以引入毫秒级抖动——这对微秒级转发延迟是致命的。isolcpus 是“筑墙”,worker_cpu_affinity 是“挂牌”,两者缺一不可。











