2026-09-17 04:43 1002 次浏览

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

很多站长优化Nginx时只盯着worker_connections,结果QPS上不去。本文从实际压测出发,拆解worker进程数、keepalive、文件描述符、sendfile与TCP栈的联动关系,给出可落地的配置片段和验证方法。

压测工具跑出几百QPS就上不去了,top一看CPU才30%,这种场景我见过太多次。大多数人第一反应是去调worker_connections,把它从1024改成65535,重启,再压——数字纹丝不动。问题根本不在那。

worker进程数和CPU核数不是随便设的

worker_processes auto 是起点,不是终点。Nginx默认让每个worker绑定一个CPU核心,但如果你的机器上还跑着MySQL、Redis或者PHP-FPM,把所有核都给Nginx反而会互相抢。我的做法是留一到两个核给系统和其他服务,剩下的给Nginx。

更关键的是worker_cpu_affinity。不设置的话,Linux调度器会把worker在核心之间来回迁移,缓存命中率下降。手动绑定之后,同样的配置在4核机器上QPS能涨15%左右。配置写法是每个worker对应一个核心掩码,别嫌麻烦。

keepalive和文件描述符的连锁反应

worker_connections 的真正含义是「每个worker能同时处理多少个连接」,它受worker_rlimit_nofile限制。如果你把worker_connections改成65535却没动系统的nofile,Nginx启动时会直接报错或者静默截断。

  • 系统层面:修改 /etc/security/limits.conf,把 nofile 提到 65535 以上
  • Nginx层面:worker_rlimit_nofile 65535
  • upstream层面:keepalive 32 到 64,别设太大,后端连接池会积压

还有一个常被忽略的点:keepalive_timeout设太长,空闲连接会占着worker的连接槽。压测场景下设15到30秒足够,真实业务可以到60秒,但别设成0,那等于关掉了长连接,每个请求都重新握手。

sendfile、tcp_nopush和TCP栈的配合

静态文件服务里,sendfile on 是标配,但单独开它效果有限。配合 tcp_nopush on,让Nginx等数据攒够一个MSS再发,减少小包数量;再配合 tcp_nodelay on,在keepalive连接上禁用Nagle算法,降低延迟。这三个是一组,缺一个都打折扣。

系统层面的TCP参数同样重要。net.core.somaxconn 默认128,高并发下队列会溢出;net.ipv4.tcp_tw_reuse 让TIME_WAIT状态的端口可以复用,对短连接场景帮助明显。这些参数改完要sysctl -p生效,别改完就忘了。

如果你在海外机房跑Nginx,网络栈的调优空间比本地更大。像美国硅谷高防服务器 XLIV这类机器,100M带宽配Gold-6133*2,压测时更容易看出参数调整的差异,因为瓶颈不在硬件上。

最后提醒一句:所有参数改完,用 ab 或 wrk 做对比压测,记录QPS、延迟P99和错误率。没有数据支撑的调优都是猜。改一个参数、压一次、记一次,比一次性改十个参数然后不知道哪个起了作用要靠谱得多。