容器中应显式配置 worker_processes 为实际可用vCPU数,而非使用 auto;需通过 cgroups 查配额(如 /sys/fs/cgroup/cpu.max),并同步调整 worker_connections、worker_rlimit_nofile、use epoll 和 multi_accept 等参数,上线后须验证进程数、CPU绑定及日志输出。

直接写 worker_processes auto; 在容器里大概率会翻车——它读的是宿主机的 CPU 信息,不是容器实际能用的 vCPU。结果就是:宿主机 64 核,Pod 只分了 2 个 vCPU,Nginx 却起了 64 个 worker 进程,疯狂争抢调度器资源,上下文切换飙升,吞吐不升反降,还可能被 OOMKilled。
先确认容器真实可用 CPU 数
别信 nproc 或 lscpu 输出的总数,要看 cgroups 配额:
- 查 cgroups v2(主流):
cat /sys/fs/cgroup/cpu.max 2>/dev/null,输出类似200000 100000表示 2 个 vCPU(200000 ÷ 100000) - 查 cgroups v1:
cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us和/sys/fs/cgroup/cpu/cpu.cfs_period_us,同样相除得 vCPU 数 - 如果两个值都是 -1,说明没设 CPU 限制,此时才按宿主机物理核数算(用
lscpu | awk '/Core.*per.*socket/ {c=$4} /Socket.*s:/ {s=$2} END {print c*s}')
配置方式要“显式 + 可验证”
靠 auto 猜不如自己算清楚再写死:
- 最稳妥:在
nginx.conf全局块中直接写worker_processes 2;(数值与 K8sresources.limits.cpu或docker run --cpus=2严格一致) - 较灵活:启动前注入配置,比如在 Docker entrypoint 或 K8s initContainer 中执行:
echo "worker_processes $(cat /sys/fs/cgroup/cpu.max | awk '{print int(\$1/\$2)}');">/etc/nginx/conf.d/worker.conf - 若坚持用 auto,必须加兜底:
worker_processes auto; worker_cpu_affinity auto;,但要求 Nginx ≥ 1.19 且内核支持 cgroups 自动探测
配套参数必须同步调
只改 worker_processes 是白搭,下面三项不匹配,轻则性能打折扣,重则启动失败:
-
worker_connections:建议设为2048~4096;若容器 ulimit -n 是 65536,4 个 worker 就配worker_connections 16384(≈ 65536 ÷ 4 × 0.9) -
worker_rlimit_nofile:设为与 ulimit -n 相同值,确保每个 worker 能打开足够文件句柄 -
use epoll;(Linux 必开)+multi_accept on;:提升单 worker 处理连接效率,尤其适合代理类负载
上线后必须验证是否真生效
别只看配置文件,进容器实测:
- 查进程数:
ps -C nginx --no-headers | wc -l,应等于1(master)+ N(workers) - 查绑定情况:
ps -eo pid,psr,comm | grep 'nginx:',确认各 worker 分布在不同 CPU ID 上(若只分配 1 个 vCPU,就该全在同一个 ID) - 查错误日志:
tail -n1 /var/log/nginx/error.log,启动行应明确打印using N processes - 查 stub_status:
curl http://localhost/nginx_status,关注Waiting连接数,持续高于 1000 优先调大worker_connections,而不是加 worker 数











