跳转到主内容
极星编程网:以代码为星,赴技术山海!

Nginx worker_processes 与 NUMA 拓扑调优:在多路服务器实现吞吐性能翻倍

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 场景下这三个参数必须联动: Nginx 在宝塔面板中轻松管理Nginx高性能Web服务器。提供可视化配置反向代理、负载均衡、SSL证书及HTTP缓存功能,一键优化高并发性能,助您高效搭建稳定、快速的网站运行环境。 下载
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 节点间的无效化频率,比任何吞吐数字都更能暴露底层亲和性缺陷。

相关文章