Nginx调优别只改worker_connections,这几个参数才是真瓶颈

2026-10-05 08:12 1011 次浏览

服务器刚上线那阵子,访问量不大,Nginx默认配置跑得好好的。等并发上来,页面开始转圈,top一看CPU没满、内存也够,就是响应慢。多数人第一反应是去改 nginx.conf 里的 worker_connections,从512改到10240,重启,发现QPS纹丝不动。问题不在这儿。

Nginx调优最容易走偏的地方,是把配置文件的参数当成唯一的旋钮。实际上瓶颈往往藏在两个地方:一是Nginx进程本身怎么用系统资源,二是Linux内核给网络连接留了多少余量。这两层不调,配置文件改出花也没用。

worker_processes 和 worker_connections,别背默认值

worker_processes 默认是1,意思是所有请求都由一个进程处理。4核机器上这就等于把另外3个核晾着。通常设成 auto,让Nginx自己读CPU核心数。但如果是16核以上的机器,全开未必好,进程间切换的开销会吃掉一部分收益,我一般先按核数设,压测后再决定要不要减。

worker_connections 的含义是单个worker能同时处理多少连接,不是总连接数。总并发上限大致等于 worker_processes 乘以 worker_connections。4核配1024,理论上限是4096个连接。听起来够用,但这里有个坑:反向代理场景下,一个客户端连接会占用两个连接数——前端一个、后端一个。所以实际能扛的客户端并发只有一半。

按我的经验,4核8G的机器,worker_connections 设2048到4096之间比较稳。设太大反而会让每个worker的内存占用上去,遇到慢连接时容易堆积。

真正卡住QPS的,是文件描述符和内核参数

配置文件里写了 worker_connections 4096,系统未必真的给得了。Linux默认单进程能打开的文件描述符是1024,Nginx每个连接都要占一个fd。worker_connections 超过1024而没调系统限制,多出来的部分根本分配不到。

需要同时改两处:

  • Nginx配置里的 worker_rlimit_nofile,设成 worker_connections 的两倍左右,比如8192
  • 系统层面的 /etc/security/limits.conf,把 nofile 的软硬限制都提上去

只改一处是新手最常见的失误。改完用 ulimit -n 确认当前shell的限制,再重启Nginx,否则配置不生效你还以为改对了。

内核参数这块,net.core.somaxconn 默认128,高并发下连接队列会溢出,建议提到65535。net.ipv4.tcp_tw_reuse 打开可以复用TIME_WAIT状态的连接,对短连接为主的场景效果明显。这几个参数加起来,4核机器扛住8000到10000 QPS是现实的,具体数字取决于业务逻辑轻重,静态文件服务会更高。

如果后端是动态应用,Nginx本身的调优空间有限,这时候更该考虑的是把静态资源和动态请求分开。秀米云的香港自营物理服务器(20M)配E5-2695V4、32G内存,跑Nginx做前端代理和静态资源分发比较合适,物理机没有虚拟化层的开销,网络中断处理也更直接。

keepalive、gzip和缓存,省的是带宽也是CPU

keepalive_timeout 默认65秒,对多数站点偏长。长连接占着worker不放,高峰期连接数会虚高。静态站点设15到30秒就够,API服务可以更短。但别设成0,频繁重建TCP连接的开销比省下的连接数更贵。

gzip 要开,但别什么都压。已经压缩过的图片、视频再走gzip纯属浪费CPU。gzip_comp_level 设4到6之间,9级压缩率提升有限,CPU开销却翻倍。gzip_min_length 设1000字节,小文件压缩收益抵不上开销。

proxy_cache 用好了能省掉大量回源请求。缓存路径挂到独立磁盘上,别和系统盘抢IO。缓存时间按业务定,新闻类60秒,静态资源可以按天。

说个取舍:开缓存意味着用户可能看到旧内容。对时效性要求高的接口,宁可不缓存,或者用 proxy_cache_bypass 对特定URL跳过。省下的那点回源带宽,换不回用户看到过期数据的代价。

压测之后才知道改对了没有

调完参数不压测等于没调。用 ab 或 wrk 跑一轮,重点看三个数:Requests per second、Time per request、Failed requests。QPS上去了但失败率也上去了,说明连接队列或者fd限制还是没配够。

压测时盯着 top 里的 wa(IO等待)和 si(软中断)。wa高说明磁盘或缓存拖后腿,si高说明网络中断处理吃CPU,这时候加worker进程没用,得从网卡多队列或者连接复用上想办法。

最后给个能直接用的结论:4核8G机器,worker_processes 设 auto,worker_connections 设2048,worker_rlimit_nofile 设8192,somaxconn 提到65535,keepalive_timeout 降到30秒,gzip_comp_level 用5。静态资源为主的站点,这套配置跑8000 QPS问题不大。动态请求多的,先去优化应用层SQL和缓存,Nginx这边调到底也就那样。至于上G口的香港大带宽服务器 XI,那是并发再上一个量级之后才需要考虑的事,别在几千QPS的阶段就把预算花在带宽上。