应将worker_processes设为物理核心数并配worker_cpu_affinity auto,以确保每个Worker独占物理核、避开超线程争抢、提升缓存命中率;需用lscpu确认真实物理核数,容器环境须按vCPU配额计算,最后通过ps和taskset验证绑定是否稳定生效。

直接在 nginx.conf 的全局块(events 块外、http 块之上)配置 worker_processes 和 worker_cpu_affinity,就能让每个 Worker 进程稳定运行在指定物理 CPU 核上,减少跨核调度、提升缓存命中率。
确认真实物理核心数,别被超线程或虚拟核误导
超线程(HT)会让一个物理核暴露为两个逻辑 CPU,但 L1/L2 缓存和执行单元是共享的。两个 Worker 挤在同一物理核上,反而争抢资源。
- 运行
lscpu | grep -E "Core\(s\) per socket|Socket\(s\)"→ 相乘得物理核心总数(例如:2 sockets × 12 cores = 24) - 对比执行
nproc --all或lscpu | grep "CPU(s):"→ 查逻辑核数(如 48,说明 HT 已开) - 容器/K8s 环境中,
nproc可能返回宿主机核数,必须以实际 vCPU 配额为准(如resources.limits.cpu: "4"就按 4 核算)
优先用 auto 模式自动绑定,省事又可靠
Nginx ≥ 1.9.10 支持 worker_cpu_affinity auto,它会自动跳过超线程对称逻辑核,把每个 Worker 绑定到不同物理核的第一个线程(如逻辑 CPU 0、2、4…),比手动写掩码更健壮。
- 物理核数为 4 → 写:
worker_processes 4;+worker_cpu_affinity auto; - 物理核数为 16 → 写:
worker_processes 16;+worker_cpu_affinity auto; - 容器限频场景可加范围限定,例如只用前 4 个逻辑 CPU:
worker_cpu_affinity auto 00001111;
手动配置需严格对齐硬件拓扑
仅当 auto 不生效、或需精细控制(如 NUMA 架构)时才手动设置。掩码位数必须等于系统逻辑 CPU 总数,且每个 Worker 对应唯一物理核。
- 4 物理核(无 HT)→ 掩码共 4 位:
worker_cpu_affinity 0001 0010 0100 1000 - 8 物理核 + HT(共 16 逻辑核)→ 推荐用前 8 个物理核的首个线程:
worker_cpu_affinity 01010101 01010101(对应逻辑 CPU 0,2,4…14) - 更易读写法:十六进制掩码,如 8 核写成
01 02 04 08 10 20 40 80 - 双路服务器(NUMA)下,用
numactl --hardware查节点,确保所有 Worker 绑定在同一 NUMA node 内
验证是否真正生效,不能只写不查
配置写完不验证,等于没调优。重点看 PSR 是否稳定、是否唯一、是否跳变。
- 重启 Nginx 后执行:
ps -eo pid,psr,comm | grep 'nginx: worker' | sort -k2,2n→ 每个 Worker 的 PSR 列应固定对应不同数字(如 0、1、2、3),不重复、不跳变 - 查某进程当前绑定:
taskset -cp→ 输出应显示只允许运行在 1 个物理核对应的一组逻辑 CPU 上(如0或0,2) - 常见失效原因:Nginx 版本低于 1.9.10、
master_process off、cgroup 限制了 CPU 可见性、配置未放在 main 块顶层











