Nginx在NUMA服务器上需设worker_processes等于单节点物理核心数并用numactl绑定CPU与内存,否则跨节点访问致延迟倍增、QPS跌超40%;双路32核应设为16而非32或auto,且须验证numastat输出本地Node占比>95%。

要让 Nginx 在单台多路 NUMA 服务器上真正实现内存本地化、低延迟、高吞吐的安全路径处理,关键不是“多开进程”,而是按 NUMA 节点物理拓扑精准切分并约束资源边界。盲目增加 worker_processes 数量反而会触发跨节点内存访问,导致延迟翻倍、QPS 下跌超 40%。
明确 worker_processes 的正确取值逻辑
这个值必须等于单个 NUMA 节点的物理核心数(非总核数、非逻辑线程数、更不能设为 auto),原因在于:
- 每个 Worker 进程在运行中会频繁申请内存(如连接缓冲区、SSL 上下文、临时文件缓存);
- 若进程被调度到 Node 0 的 CPU,却从 Node 1 分配内存,就会走 QPI 总线,延迟增加 50–100ns;
-
auto模式仅读取/proc/cpuinfo总逻辑核数,完全无视 NUMA 节点划分,无法保证本地性。
例如双路服务器(每路 16 物理核,共 32 核),典型 NUMA 布局为:
- Node 0:CPU 0–15,本地内存 64GB
- Node 1:CPU 16–31,本地内存 64GB
→ 此时应设worker_processes 16(即单节点物理核数),而非 32 或 64。
必须同步完成 CPU 与内存的双重绑定
仅靠 worker_cpu_affinity 固定 CPU 不够——Nginx 本身不控制内存分配节点。必须用 numactl 封装启动,强制子进程继承本地内存策略:
- 在 systemd 服务中修改
/etc/systemd/system/nginx.service.d/override.conf:[Service] ExecStart= ExecStart=/usr/bin/numactl --cpunodebind=0 --membind=0 /usr/sbin/nginx -g 'daemon on; master_process on;'
- 若需双节点全利用,推荐部署两个独立 Nginx 实例(分别绑定 Node 0 和 Node 1),或写启动脚本分片调用
numactl,避免单 master 管理跨节点 worker 带来的调度不确定性。
配套参数需协同收紧,防止资源错配
-
worker_rlimit_nofile设为 100000+,并同步调高系统fs.file-max和用户级nofile限制; -
worker_connections建议 ≤32768,因每个连接约占用 240 字节内存,过高会导致单 Worker 内存暴涨,诱发跨节点分配; - 静态服务务必开启
sendfile on和tcp_nopush on,减少内核态拷贝与跨节点 page cache 访问; - 禁用
accept_mutex off(高并发下需实测,NUMA 场景下开启可能加剧锁争用)。
验证是否真正生效,重点看内存而非 CPU
- 查 Worker PID:
ps -eo pid,comm,args | grep 'nginx: worker' - 对每个 PID 执行
numastat -p <PID>,观察Total行下各 Node 的占比:- 理想状态:绑定 Node 的 Total 占比 >95%,远端 Node 接近 0;
- 若
Node 1 Total显著非零,说明内存亲和失败,需检查 BIOS 是否启用了 Node Interleaving(必须关闭)。
不复杂但容易忽略


















