必须绑定CPU物理核以避免缓存抖动和跨NUMA延迟;推荐worker_cpu_affinity auto(≥1.9.10),手动配置需按物理核顺序设掩码,同步关accept_mutex、开multi_accept,并用ps/taskset验证绑定效果。

直接用 worker_cpu_affinity 绑定 CPU 亲和性,核心不是凑几个“1”,而是让每个 Nginx worker 独占一个物理核、避开超线程干扰、防止跨 NUMA 节点调度,并验证真正生效。
先确认真实 CPU 拓扑
别看“CPU(s): 32”就设 32 个 worker。运行:
-
lscpu | grep -E "(CPU\(s\)|Core\(s\) per socket|Socket\(s\)|NUMA)"—— 看清物理核数、插槽数、NUMA 节点数 - 例如输出含 “8 CPU(s), 4 Core(s) per socket, 2 Socket(s), NUMA node(s): 2”,说明是双路服务器,共 8 逻辑核(无超线程),分属两个 NUMA 节点
- 再用
cat /proc/cpuinfo | grep "physical id\|core id" | sort -u辅助确认物理核映射关系
配置 worker\_cpu\_affinity 的两种写法
推荐优先用 auto 模式,省错又适配云环境和容器:
-
worker_processes auto;+worker_cpu_affinity auto;—— Nginx ≥ 1.9.10 自动按物理核顺序分配,跳过超线程对称核 - 手动写掩码时,位序从右往左对应 CPU 0、1、2……,每组掩码长度 = 系统逻辑 CPU 总数
- 4 物理核(无超线程):写
worker_cpu_affinity 0001 0010 0100 1000; - 8 物理核 + 超线程(共 16 逻辑核),只用前 8 个物理核的首个线程(逻辑 ID 0,2,4…14):可写
worker_cpu_affinity 0101010101010101;或更稳妥的十六进制形式01 02 04 08 10 20 40 80 - 容器中若只分配了 2 个 vCPU,掩码必须只写两组(如
01 10),否则启动失败或退化为默认调度
必须同步调整的关键配套项
光写 worker_cpu_affinity 不调其他参数,性能可能不升反降:
- 确认
accept_mutex off;(Nginx ≥ 1.11.3 默认已关),避免多个 worker 争抢 accept 锁导致串行阻塞 - 在
events块中启用multi_accept on;,让单次事件循环尽可能多地接受连接 - 适当调高
worker_connections(如 10240 或 65535),并确保系统级ulimit -n和fs.file-max匹配 - 把网卡软中断(softirq)也绑定到相同 CPU 核,避免网络包处理与 worker 跨核搬运数据
验证是否真正生效
重启 Nginx 后,用三组命令交叉验证:
-
ps -eo pid,args,psr | grep 'nginx: worker' | sort -k3,3n—— 查看每个 worker 实际运行在哪颗逻辑 CPU 上(psr列),应为固定值且互不重复 -
taskset -cp $(pgrep -f "nginx: worker")—— 显示每个 worker 进程当前实际绑定的 CPU 列表 -
cat /proc/$(pgrep -f "nginx: worker" | head -1)/status | grep -E "(Cpus_allowed|Cpus_allowed_list)"—— 查底层允许范围,确认没被 cgroup 或容器限制截断 - 若多个 worker 显示相同
psr值,常见原因包括:Nginx 版本低于 1.9.10、worker_processes未设具体数值(非auto时该指令不生效)、或宿主机未透出完整 CPU topology


















