关键差异在于资源可见性:物理机可依赖auto并验证物理核数,虚拟机必须显式设为vcpu数,否则auto会误读宿主机核数导致调度争抢;无论哪种环境,都须配worker_cpu_affinity、worker_rlimit_nofile及epoll事件模型。

虚拟机和物理机上配置 worker_processes 的关键差异,不在于“能不能设成 auto”,而在于“系统能否真实反映可用 CPU 资源”。物理机能直接读取硬件拓扑,虚拟机则常被抽象层遮蔽——配错会导致进程数远超实际 vCPU 配额,引发严重调度争抢。
物理机:可依赖 auto,但需验证物理核数
物理服务器没有虚拟化层干扰,worker_processes auto; 在 Nginx 1.3.8+ 中会读取逻辑 CPU 数。但这不是最终推荐值,因为超线程(HT)带来的逻辑核对 Nginx 收益有限,还可能加剧缓存争用。
- 先运行
lscpu | grep -E "Core\(s\) per socket|Socket\(s\)",相乘得物理核心总数(如 2×12=24) - 起点设为该物理核数,例如 24 核 →
worker_processes 24; - 必须搭配
worker_cpu_affinity auto;(Nginx ≥1.9.10),它能自动跳过 HT 对称逻辑核,绑定到独立物理核 - 若业务以静态文件、反向代理为主(I/O 密集),可尝试减半(如 12),观察 QPS 和
cs(上下文切换)是否更稳
虚拟机:禁用 auto,必须显式指定 vCPU 数
多数虚拟化平台(尤其是旧版 KVM、VMware、OpenVZ)中,nproc 或 lscpu 返回的是宿主机逻辑核数,而非分配给当前 VM 的 vCPU 数。此时 auto 会静默起满几十个 worker,全部挤在 2~4 个 vCPU 上,实测 QPS 可降 10% 以上。
- 查清你被分配的 vCPU 数量:在 VM 内运行
nproc仅作参考;应以虚拟化管理界面或cat /sys/fs/cgroup/cpu.max(cgroups v2)为准 - 显式写死,例如分配了 4 个 vCPU →
worker_processes 4; - OpenVZ 等老旧环境常返回
nproc = 1,auto会退化为单进程,必须强制覆盖 - 容器/K8s 同理:必须与
resources.limits.cpu: "2"严格一致,写worker_processes 2;
共用资源场景:预留核心,避免干扰
无论物理机还是虚拟机,只要 Nginx 不是独占型部署(比如和 MySQL、Redis 或其他中间件同机),就必须为其他服务留出计算资源。
- 预留 1~2 个物理核或 vCPU,worker 进程数设为
$(nproc --all) - 2(需在启动脚本中执行) - 尤其注意数据库类服务对 CPU 缓存敏感,与 Nginx 共享 L3 缓存时,未预留易导致响应毛刺
- 监控
vmstat 1中的cs(每秒上下文切换)和us(用户态 CPU 使用率),若cs > 5000且us持续高于 80%,大概率是 worker 过多或绑核失效
配套动作缺一不可
只调 worker_processes 是无效的。以下三项必须同步生效:
-
worker_cpu_affinity:必须开启,推荐auto或手动掩码,否则 Linux 调度器会频繁迁移进程,L2 缓存预热失效 -
worker_rlimit_nofile 65535:每个 worker 打开的文件描述符上限,需匹配worker_connections,并确保系统级ulimit -n≥ 65535 -
events { use epoll; multi_accept on; }:Linux 下固定用epoll;multi_accept开启后,一个事件可接受多个连接,降低唤醒次数











