Nginx 调优别只改 worker_connections,这几个参数才是卡顿的根子

2026-10-09 11:17 1005 次浏览

很多站长把 Nginx 装完就丢在那里跑,配置文件里除了 server_name 和 root 之外几乎没动过。平时访问量小看不出问题,一旦流量上来或者被扫到,502、504 就开始往外冒。真正让人头疼的是,打开监控一看 CPU 和内存都没跑满,机器明明还有余力,请求却堆在门口进不来——这类问题十有八九不在带宽,而在 Nginx 那几个默认值上。

下面按「先看连接数、再治超时、最后压传输」的顺序说,每一步都给出具体参数和它换回来的东西。

worker_connections 不是越大越好,先算清楚系统上限

Nginx 默认的 worker_connections 是 512,worker_processes 是 1。也就是说默认状态下这台机器最多同时处理 512 个连接,哪怕你买的是 32G 内存的独立服务器也一样。

常规做法是把 worker_processes 设成 auto,让它跟 CPU 核心数走。worker_connections 则要看两件事:系统允许的单进程文件描述符上限,以及每台机器实际要扛多少并发。我一般会先把系统的 fs.file-max 调到 65535 以上,再在 Nginx 里把 worker_connections 放到 10240 左右。

这里有个容易忽略的地方:一个浏览器连接通常会占用 2 个 worker 连接(一个用于客户端,一个用于上游),所以配置值要留出余量。512 的默认值放到今天,连一台普通企业站的峰值都顶不住。

keepalive_timeout 默认 75 秒,长连接在拖慢你的服务器

Nginx 默认 keepalive_timeout 是 75 秒,意思是客户端连上来之后,服务器会为它保留 75 秒的连接不释放。访问量小的时候这没什么,但每个空闲连接都要占一个 worker_connections 名额。

假设你有 8000 个并发连接,其中 6000 个是挂在那里没动静的长连接,实际能用来干活的就只有 2000 个名额。这就能解释为什么监控里 CPU 负载不高、请求却排队的现象。

我的处理方式是把 keepalive_timeout 压到 15 到 30 秒之间,同时给 keepalive_requests 设一个上限,比如 1000,让单个连接处理完一定数量的请求后主动断开,避免个别客户端长期霸占名额。代价是客户端会多一些重连开销,但这个开销远小于连接池被占满带来的延迟。

真正拉开差距的是 gzip 和 sendfile 这两个开关

前面两步解决的是「能不能接住」,这一步解决的是「接住之后传得快不快」。静态资源多的站点,gzip 打开和不打开,传输量能差出三四倍。

  • gzip on,gzip_comp_level 建议放 4 到 6,再往上压缩率提升有限但 CPU 明显吃紧;
  • gzip_min_length 设 1024,太小的文件压缩反而更慢;
  • gzip_types 至少覆盖 text/css、application/javascript、application/json 这几类。

sendfile 和 tcp_nopush 一起打开,可以让内核直接把文件送到网卡,省掉用户态和内核态之间的拷贝。图片、CSS、JS 这类静态文件多的站,这两个开关的效果比调 worker 参数更直接。

如果你的业务本身带宽吃紧,比如视频切片、大文件下载,单靠 gzip 已经不够用,那就得从机器层面解决。像 香港自营国际物理服务器③ 这种 E5-2650L 双路 16 核 32 线程、32G 内存配 100M 带宽的配置,跑高并发 Nginx 前端比较从容,月付 900 元这个价位在香港独立服务器里算克制。带宽再往上走、或者面向欧美用户,硅谷那边的 美国硅谷大带宽服务器 XVIII 是 G 口起步,E5-2683v4 双路 64G,月付 568.50 美元,适合下载类业务。

但换机器之前,先把上面那几个参数调对,很多卡顿其实不需要多花钱就能解决。

调完记得压测,别凭感觉判断

改完配置用 ab 或者 wrk 打一轮,重点看三组数字:Requests per second、Time per request 的均值、以及失败请求数。如果失败数还是集中在连接被拒,说明 worker_connections 或系统 fd 上限没到位;如果是响应时间随并发线性上升,那瓶颈多半在后面(数据库、上游应用),继续调 Nginx 意义不大。

最后给一个可执行的结论:日 PV 十万以内的站,把 worker_processes 设 auto、worker_connections 调到 10240、keepalive_timeout 压到 30 秒、gzip 开到 level 5,一台 4 核 8G 的机器就够用了,没必要上高配。日 PV 百万级、静态资源占比高的,再考虑把带宽和内存往上加,优先加内存而不是加核数。