worker_cpu_affinity是释放Nginx多核并发潜力的关键配置,通过绑定worker进程到指定CPU核心,避免调度迁移、提升缓存命中率并降低NUMA跨节点延迟;需先用lscpu确认真实拓扑,优先使用auto模式,配合关闭accept_mutex、开启multi_accept等调优项,并通过ps和taskset验证生效。

在高性能多路服务器上,worker_cpu_affinity 不是锦上添花的配置项,而是释放 Nginx 多核并发潜力的关键一环。它让每个 worker 进程稳定运行在指定 CPU 核心上,避免调度迁移、提升缓存命中率,并减少跨 NUMA 节点访问延迟。
确认真实 CPU 拓扑再动手
别直接套用“8核就写 8 个掩码”。先运行:
lscpu | grep -E "(CPU\(s\)|Core|Socket|NUMA)"
重点关注三项:
- CPU(s):逻辑核心总数(含超线程)
- Core(s) per socket 和 Socket(s):判断物理核心数与插槽数
- NUMA node(s):若大于 1,需考虑内存局部性
例如输出显示 “8 CPU(s), 4 Core(s) per socket, 2 Socket(s), NUMA node(s): 2”,说明是双路 Xeon,共 4 物理核 ×2 = 8 逻辑核,分属两个 NUMA 节点。此时应优先让 worker 绑定在同一 NUMA node 内的核心(如 node 0 的 core 0–3),而非跨节点轮排。
绑定写法:auto 优先,手动留底
Nginx 1.9.10+ 支持 auto,推荐作为默认起点:
worker_processes auto;<br>worker_cpu_affinity auto;
它会按逻辑核顺序自动分配,等价于显式写出完整掩码,且适配虚拟化环境(如 KVM、Docker 中 CPU topology 可能受限)。仅在以下情况改用手动模式:
- 需预留核心给数据库或监控进程(如 16 核机器只启用 12 个 worker)
- 超线程场景下希望一对 hyper-thread 共享一个 worker(如
worker_cpu_affinity 0101 1010) - NUMA 架构中严格限定某 node(如
worker_cpu_affinity 00001111 00001111表示只用前 4 核)
注意:掩码位序从右向左对应 core 0、core 1…,0001 是 core 0,1000 是 core 3。
必须同步调优的配套参数
只设 worker_cpu_affinity 不调整其他项,性能可能不升反降。重点检查:
-
关闭 accept_mutex:Nginx ≥ 1.11.3 默认已关,确认配置中无
accept_mutex on;否则多个 worker 仍争抢 accept 锁 -
开启 multi_accept:加在
events块内:multi_accept on;,让单次事件循环尽可能多地建立连接 -
匹配 worker_connections:例如设了 8 个 worker,
worker_connections 10240;总并发能力才达 81920;同时确保系统级限制足够:ulimit -n 1048576 -
容器环境特殊处理:K8s 或 Docker 中,不能依赖
auto自动识别——需根据 cgroups 分配的 vCPU 数量显式设置,如worker_processes 4;并搭配worker_cpu_affinity auto;
验证是否真正生效
重启 Nginx 后,分两步验证:
- 查各 worker 实际运行在哪颗 CPU 上:
ps -eo pid,psr,comm | grep 'nginx: worker'
输出中第二列(psr)应呈现分散值,如 0、1、2、3 —— 若全为 0,说明绑定失败。
- 查亲和性掩码是否写入:
taskset -cp $(pgrep -f "nginx: worker" | head -1)
返回类似
pid 12345's current affinity list: 2,表示绑定到 core 2。
若发现多个 worker 显示同一 psr 值,或 taskset 返回允许所有核心(如 0-15),说明配置未加载或被覆盖(常见于 include 路径误读、语法错误导致整段 events/main 被跳过)。











