2026-09-22 02:42 1001 次浏览

Nginx 调优别只改 worker_connections,这几个隐藏参数才是瓶颈所在

很多站长照着网上教程改了 worker_processes 和 worker_connections,QPS 却纹丝不动。问题往往出在连接复用、文件描述符上限和内核参数没对齐。这篇从真实压测数据出发,讲清楚 Nginx 性能优化里最容易被忽略的几个环节。

不少站长折腾 Nginx 优化时,第一反应就是打开 nginx.conf,把 worker_processes 改成 auto,再把 worker_connections 从 1024 拉到 65535,保存、reload、压测——结果 QPS 只涨了两三百,CPU 倒是先跑满了。这种「改了个寂寞」的经历,几乎每个运维都遇到过。

问题在于,Nginx 的并发能力从来不是单个参数决定的。它是一条链路:内核给多少文件描述符、连接能不能复用、后端响应有多快、磁盘 IO 扛不扛得住。只调 Nginx 自己,等于给水管换了个大龙头,上游还是细管子。

先搞清楚你的瓶颈到底在哪一层

压测之前别急着改配置。用 abwrk 跑一轮,同时开着 top -H 看 CPU 分布:如果单核跑满、其他核闲着,说明 worker 进程没吃满多核;如果 %wa 很高,那是磁盘 IO 拖后腿;如果 %sy 偏高,多半是系统调用和连接建立太频繁。

还有一个常被忽略的信号:netstat -s | grep -i listen 里的 overflow 计数。只要这个数字在涨,说明 accept 队列溢出,新连接被内核直接丢掉,这时候再怎么调 worker_connections 都没用。

三个真正影响吞吐的参数

  • worker_rlimit_nofile:很多人只改了 worker_connections,却没动系统的 nofile 限制。Nginx 主进程能打开的文件数上不去,worker_connections 设再大也是空中楼阁。配置文件里加一行 worker_rlimit_nofile 65535;,再确认 ulimit -n 和 systemd 的 LimitNOFILE 都放开了。
  • keepalive 连接池:反向代理场景下,Nginx 到后端如果每个请求都新建 TCP 连接,握手开销能吃掉三成以上性能。在 upstream 块里加 keepalive 64;,同时把 proxy_http_version 设为 1.1、proxy_set_header Connection "";,让长连接真正生效。
  • sendfile 与 tcp_nopush 组合:静态资源多的站点,sendfile on; 配合 tcp_nopush on; 能减少数据包数量;但如果是小文件密集的 API 服务,反而要开 tcp_nodelay on; 降低延迟。这两个参数经常互相打架,得按业务类型选。

内核参数不调,Nginx 白忙一场

Linux 默认的 somaxconn 只有 128,高并发下 accept 队列分分钟溢出。把 net.core.somaxconn 提到 65535,net.ipv4.tcp_max_syn_backlog 同步拉高,再把 net.ipv4.tcp_tw_reuse 打开,TIME_WAIT 堆积的问题能缓解不少。

另外别忘了 net.core.rmem_max 和 wmem_max,大文件传输场景下默认缓冲区太小,带宽跑不满。这些参数写进 sysctl.conf 后记得 sysctl -p 生效。

说到底,Nginx 调优是个系统性活儿。单机优化做到头之后,真正扛量的还得靠硬件底子——CPU 主频、内存带宽、网卡队列这些。如果业务已经跑在物理服务器上,调优空间会比虚拟化环境大得多,尤其是需要独占 CPU 和万兆网卡的大流量场景,一台 美国西雅图大带宽服务器 配合上面的内核参数,能比默认配置多扛好几倍的并发。