worker_cpu_affinity的核心作用是让每个worker进程独占一个物理cpu核,避免缓存迁移开销,解决“一核过载、多核闲置”问题;需配合accept_mutex off、multi_accept on及系统文件描述符调优才能生效。

worker_cpu_affinity 的核心作用,是打破 Linux 默认调度带来的“一核过载、多核闲置”现象。它不靠增加并发数,而是让每个 worker 固定驻留一个物理核,把缓存、TLB、连接状态等热点数据稳在本地,避免迁移开销——这才是解决“一核有难、多核围观”的底层路径。
先确认是不是真问题
不是所有 CPU 不均都是配置问题,得先排除干扰:
- 用 mpstat -P ALL 1 观察各核实时利用率,连续几秒出现某核长期 ≥95%、其余核普遍<30%,才属典型“围观”
- 检查是否启用了 accept_mutex on(旧版本默认开启):它会让所有 worker 排队抢 accept 锁,本质是人为串行化,绑再好的核也白搭
- 确认 worker_processes 数量没超过物理核心数——比如 8 物理核却设了 16 个 worker,必然争抢
用 auto 模式快速破局
Nginx 1.9.10+ 的 worker_cpu_affinity auto 是最省心也最稳妥的解法,它自动跳过超线程逻辑核,只绑定真实物理核:
- 配法简洁:worker_processes auto; + worker_cpu_affinity auto;
- 例如 16 逻辑核(8 物理 + HT),auto 默认只启用前 8 个物理核,每个 worker 独占一个,彻底避开超线程争抢
- 若只想用前 4 核,写成 worker_cpu_affinity auto 00001111;(后缀十六进制掩码限定范围)
手动掩码只在必要时介入
仅当 auto 不够用时才手动配,比如 NUMA 双路服务器或需预留核心给其他服务:
- 双路 Xeon 共 24 逻辑核(node0: 0–11,node1: 12–23),想让 12 个 worker 全在 node0 内运行,可写:
worker_processes 12;
worker_cpu_affinity 000000000000111111111111 000000000000111111111111 …(重复 12 次) - 关键原则:掩码组数 = worker 数;每组位宽 = 系统逻辑核总数;最低位(最右)对应 core 0;禁止重复掩码(如 0001 0001)
- 验证是否真绑上:用 ps -eo pid,args,psr | grep 'nginx: worker' 查 PSR 列,应为 0、1、2…一一不重复
必须同步调的配套项
单靠绑核不能解决问题,以下三项不调,绑得再准也难破局:
- accept_mutex off;(1.11.3+ 默认已关,旧版务必显式关闭)—— 解除 accept 锁瓶颈
- multi_accept on; —— 让单个 worker 一次收多个就绪连接,填满绑定核的处理能力
-
worker_connections 10240; 并同步调大系统限制:
→ ulimit -n 65535(改 /etc/security/limits.conf)
→ fs.file-max = 2097152(改 /etc/sysctl.conf)










