worker_processes auto更稳因它具备NUMA感知能力,能自动按本地内存节点均匀分发worker进程,避免跨节点访问导致的延迟翻倍与缓存命中率暴跌;手动设32核则易使部分进程运行在远端NUMA节点,引发CPU不均衡、numa_foreign升高及QPS异常下降。

worker_processes auto 为什么比手动设核数更稳
在双路或四路 NUMA 架构服务器上,手动写死 worker_processes 32 很可能让一半 worker 进程跑在远端 NUMA 节点上——它们访问内存要跨 QPI/UPI 总线,延迟翻倍,缓存命中率暴跌。而 worker_processes auto 从 Nginx 1.3.8 起就内置 NUMA 感知逻辑:它读取 /sys/devices/system/node/ 下的节点拓扑,优先把 worker 进程均匀分发到每个本地内存节点对应的核心组,避免跨节点调度。
常见错误现象:
• 压测时 CPU 利用率不均衡(比如 32 核里只有 16 核跑满)
• numastat -p $(pgrep nginx | head -1) 显示 numa_hit 低、numa_foreign 高
• 同样配置下,单路服务器 QPS 是双路的 1.8 倍以上
实操建议:
• 必须用 worker_processes auto,不要手算总核数
• 验证是否生效:启动后执行 ps -eo pid,psr,comm | grep nginx,观察各 worker 的 CPU 编号是否自然聚类(如 0–15 和 32–47 分两组)
• 若发现进程仍散落在所有逻辑 CPU 上,检查内核是否禁用了 NUMA(cat /proc/cmdline | grep numa=off)
worker_cpu_affinity auto 在 NUMA 场景下的真实行为
worker_cpu_affinity auto 不是简单地按顺序绑核,而是配合 worker_processes auto 的 NUMA 分组结果,为每个 worker 自动分配同一 NUMA 节点内的连续核心。例如双路 32 核(每路 16 核),它会生成类似 worker_cpu_affinity 000000000000ffff 000000000000ffff0000000000000000 的掩码(前 16 位和后 16 位分别对应两个节点)。
容易踩的坑:
• 手动写二进制掩码时错位(比如 32 核写成 32 位但实际有超线程,逻辑 CPU 数是 64)
• 在启用了 CPU 隔离(isolcpus)的系统上,auto 可能绑定到被隔离的核心,导致 worker 启动失败(报错 bind() to 0.0.0.0:80 failed (98: Address already in use))
• Docker/K8s 环境中,容器未声明 --cpuset-cpus,宿主机 worker_cpu_affinity 会失效
实操建议:
• 先确认 NUMA 节点布局:lscpu | grep "NUMA node" 或 numactl --hardware
• 若需精细控制,改用显式掩码,但必须按节点分组写,例如双路 16c/32t:worker_processes 32; worker_cpu_affinity 0000000000000000000000000000ffff 0000000000000000ffff000000000000;
• 容器部署时,worker_cpu_affinity 应与 --cpuset-cpus 保持一致
NUMA 感知调优必须同步调整的三个关联参数
只调 worker_processes auto 和 worker_cpu_affinity auto 不够,NUMA 场景下这三个参数必须联动:
worker_rlimit_nofile:每个 worker 进程打开的文件描述符上限,必须 ≥ worker_connections × 1.2,否则高并发时触发 accept() failed (24: Too many open files),且 NUMA 节点间 fd 表不共享,不能靠全局 ulimit 补救。events { multi_accept on; }:启用后,每个 worker 在一次 epoll wait 中批量获取多个新连接,减少跨节点唤醒次数;关闭时,连接请求可能被不同节点的 worker 竞争,引发缓存抖动。http { sendfile on; }:零拷贝依赖 page cache 本地性,若文件页在远端 NUMA 节点,sendfile 反而比 read/write 更慢;必须配合 echo 1 > /proc/sys/vm/numa_balancing 让内核主动迁移热页到本地节点。
性能影响:
• 未调 worker_rlimit_nofile:QPS 卡在 3 万左右即触顶
• multi_accept off:在 10 万连接压测中,context switches/sec 高出 40%
• sendfile on + 无 NUMA 页迁移:静态文件响应延迟 P99 从 8ms 涨到 42ms
验证 NUMA 优化是否真正生效的三步法
别信配置文件写了就等于起效。真实生产环境必须走这三步:
• 第一步:确认 worker 进程物理分布
执行 ps -eo pid,psr,comm | grep 'nginx: worker' | sort -k2n,看 PID 是否按 CPU 编号自然分簇(如 PID 1234→CPU 0–15,PID 1235→CPU 32–47)
• 第二步:检查内存访问局部性
运行 numastat -p $(pgrep nginx | head -1),重点看 numa_hit 占比是否 >95%,numa_foreign 是否 other_node 持续增长,说明有跨节点内存分配
• 第三步:压测对比关键指标
用 wrk 或 go-wrk 对比开启 NUMA 优化前后:
– 同等 QPS 下的 CPU sys 时间(应下降 20%+)
– P99 延迟(应收窄且稳定)
– perf stat -e cycles,instructions,cache-misses -p $(pgrep nginx | head -1) 中 cache-misses rate(应从 >8% 降至
最容易被忽略的是第三步里的 cache-misses:它直接反映 CPU 缓存行在 NUMA 节点间的无效化频率,比任何吞吐数字都更能暴露底层亲和性缺陷。



















