物理核心数是CPU芯片上真实存在的独立硬件处理单元,逻辑核心则是通过超线程技术虚拟出的执行单元;物理核拥有完整独立资源,逻辑核共享物理核资源,性能上限低于物理核。

直接设为物理 CPU 核心数,不是逻辑核数,也不是“越多越好”。每个 worker 是单线程事件模型,只有绑定到独立物理核,才能减少调度干扰、提升 L1/L2 缓存命中率。
先确认真实物理核心数
别被超线程(HT)或容器虚拟核数带偏:
- 执行 lscpu | grep -E "Core\(s\) per socket|Socket\(s\)" → 相乘得物理核总数(例如:2 sockets × 12 cores = 24)
- 执行 nproc --all → 查逻辑核数(仅作对比参考)
- 常见误区:8c16t 机器若设
worker_processes 16,两个 worker 可能挤在同一物理核上,争抢缓存
按环境选择配置方式
auto 不是万能的,不同部署环境要区别对待:
-
物理服务器:推荐
worker_processes auto;+worker_cpu_affinity auto;(Nginx ≥ 1.9.10),自动跳过超线程对称逻辑核,优先绑定物理核的第一个线程 -
Docker 容器:若运行时限制了 2 个 vCPU,就写
worker_processes 2;,并配worker_cpu_affinity auto; -
Kubernetes Pod:必须与
resources.limits.cpu: "4"严格对齐,写worker_processes 4;;用 auto 前需确认镜像支持 cgroups v2 -
OpenVZ 或老旧虚拟化:nproc 常返回 1,auto 会退化为单进程,必须显式覆盖,如
worker_processes 4;
结合业务类型微调数值
物理核数只是起点,最终值要看负载特征:
- I/O 密集型(静态文件、高命中反向代理):通常 1~4 个 worker 就够用,再多收益递减
-
CPU 密集型(全站 HTTPS、实时 gzip、OpenResty 中大量 Lua):可设为物理核数,但要监控
vmstat 1中的cs(上下文切换)是否异常升高 - 混合或长连接场景(WebSocket、gRPC、上游响应慢):建议设为物理核数的 1/2~3/4(如 16 核设 8~12)
-
资源共用服务器(Nginx 和数据库同机):预留 1~2 个核,设为
$(nproc --all) - 2
必须配套生效的关键参数
只改 worker_processes 没用,得一起调:
-
绑定核心:
worker_cpu_affinity auto;(推荐)或手动掩码(如四核:0001 0010 0100 1000) -
提升文件描述符上限:在 main 块加
worker_rlimit_nofile 65535;,并确保系统级ulimit -n≥ 该值 -
事件模型优化:events 块中写
use epoll; multi_accept on; worker_connections 4096;
验证是否真正生效:重启后执行 ps -eo pid,psr,comm | grep nginx,每个 worker 的 PSR 列应稳定落在不同 CPU 编号上;再用 taskset -cp 确认亲和性设置已加载。若 PSR 频繁跳变,检查 master_process on; 是否开启、配置是否在 main 块、系统是否禁用了 CPU 亲和力策略。











