Worker进程数应设为物理核心数而非逻辑核数,需用lscpu查Core(s) per socket与Socket(s)相乘得出,并按场景调整:长连接减半、I/O密集用满、SSL加解密可略超;同时必须同步配置worker_rlimit_nofile、worker_connections(=ulimit-n÷worker_processes×0.9)和use epoll。

Worker进程数设得比物理核心数还高,多数情况下不仅不提升性能,反而加剧上下文切换和锁竞争,导致CPU空转、响应变慢。 宝塔默认常设为 auto,但容器环境、超线程开启、或混部PHP/MySQL时,这个“自动”恰恰是问题源头。
怎么查你当前实际有多少物理核心
别信 nproc 或 lscpu | grep CPU 里带 Thread(s) per core 的总数——那可能是超线程虚拟出来的逻辑核。真实可用的物理核心数要这样看:
- 执行
lscpu | grep "Core(s) per socket"和lscpu | grep "Socket(s)",相乘即物理核心总数(例如 2 sockets × 4 cores = 8 核) - 容器内运行时,必须看
cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us:如果值是-1,说明没限制,按宿主机物理核算;如果是200000(即 2 核配额),就只能设worker_processes 2 - 宝塔面板里“系统信息”页显示的“CPU核心数”有时会把超线程当物理核,不可直接采信
不同场景下该设多少个Worker
不是所有负载都适合“等于物理核数”。关键看瓶颈在哪:
-
大量WebSocket/gRPC长连接:每个
worker要维持数千连接,内存和文件描述符压力大,建议设为物理核数的1/2~3/4(如 8 核 → 设4或6) -
纯静态文件下载(未开
sendfile)或磁盘I/O密集:过多worker会争抢磁盘队列,反而降低吞吐,严格用物理核数(worker_processes 8,不是16) -
启用了软件SSL加解密(无硬件加速卡)且QPS高:可比物理核多设
1~2个,分担CPU计算压力 -
容器中跑Nginx,且
cpu.shares或cfs_quota_us已限核:必须按cgroup限额设,设多了等于白占调度器资源
改完配置后必须同步调的三个参数
只改 worker_processes 是无效的,下面三项不匹配,轻则报错,重则启动失败:
-
worker_rlimit_nofile必须等于你为Nginx用户设的ulimit -n值(宝塔常见是www用户,需在/etc/security/limits.conf里设www soft nofile 65535和www hard nofile 65535) -
worker_connections建议按公式算:ulimit -n ÷ worker_processes × 0.9(留10%余量),例如ulimit -n是 65535、worker_processes是 4,则设worker_connections 14745(65535÷4×0.9≈14745) -
use epoll;必须显式写在events { }块里,Linux下不写可能 fallback 到低效的select,尤其在高并发时差异明显
宝塔里怎么安全修改并验证
别直接改主配置文件然后点“重载”,容易因语法错误导致Nginx挂掉。正确顺序是:
- 先用宝塔终端执行
nginx -t测试语法(它会读取你刚保存但未生效的配置) - 确认返回
successful后,再进宝塔面板 → 网站 → 设置 → 配置文件 → 修改nginx.conf中的worker_processes和配套参数 - 保存后点击右上角「重载Nginx」,不是「重启」——重载能平滑切换,旧连接不受影响
- 最后用
ps aux | grep nginx看 master 进程下是否只有预期数量的 worker 进程(注意排除grep自身那行)
真正决定效果的是压测结果,不是配置数字。哪怕你设了 worker_processes 1,只要 worker_connections 和系统限制跟得上,千级QPS照样稳。容易被忽略的是:改完后一定要检查 cat /proc/$(pgrep nginx)/limits | grep "Max open files",确保 worker 进程看到的限制确实是你设的值,而不是被 systemd 或 limits.conf 某处覆盖了。


















