Nginx 调优别背参数:worker 进程、连接数与缓存怎么配才不掉链子

2026-10-03 11:19 1008 次浏览

一台 4 核 8G 的机器,装完 Nginx 把站点丢上去,默认配置跑静态页面,用 ab 压一下大概 2000 QPS 就上不去了。CPU 没满,内存也空着一半,可请求就是排在那里。多数人这时候会去翻网上那些参数清单,改完发现数字没涨多少,反而偶尔冒 502。问题不在改没改,而在改的东西跟瓶颈对不上。

调 Nginx 之前先想清楚一件事:你压的是静态文件、PHP 反代,还是 WebSocket 长连接。这三种场景吃的资源不一样,参数优先级也完全不同。下面按这个顺序拆。

worker 进程数不是越多越好,核数对上就行

worker_processes 这条我一般直接写 auto,让 Nginx 按 CPU 核数自己填。4 核就起 4 个,8 核就 8 个,手动写死反而容易在换机器时忘了改。

但 auto 只认核数,不认你机器上还跑着什么。如果同一台机器上还有 MySQL 或者 PHP-FPM 在抢 CPU,把 worker 数压到核数的一半更稳。我见过把 worker_processes 写成 16 跑在 4 核机器上的配置,进程之间来回抢时间片,QPS 比默认还低。

worker_cpu_affinity 可以把每个 worker 绑到固定核上,减少上下文切换。4 核就写 0001 0010 0100 1000。这项收益不算大,静态站大概 5% 上下,但配置成本低,顺手加上没坏处。

worker_rlimit_nofile 要跟系统 ulimit -n 一起看。默认 1024 在高并发下会先撞文件描述符上限,报错是 accept() failed,不是 502。把它设到 65535,同时确认 /etc/security/limits.conf 里 nofile 也放开了,不然重启就回去了。

连接数、超时和 keepalive 是真正卡 QPS 的地方

worker_connections 默认 1024,意思是每个 worker 最多同时处理 1024 个连接。4 核就是 4096 个,反代场景下每个客户端会占两个连接(前端一个、后端一个),实际能扛的并发要再砍一半。设到 10240 是常见做法,前提是前面 worker_rlimit_nofile 已经放开。

比连接数更容易被忽略的是 keepalive_timeout。默认 65 秒,意味着一个空闲连接要占着资源待够 65 秒才释放。压测时连接堆得飞快,TIME_WAIT 能到几万条。静态站调到 15 到 20 秒足够,反代后端可以再短一点。

反代场景还要配 upstream 里的 keepalive。默认 Nginx 到后端是短连接,每个请求都重新握手。加一段:

  • upstream 块里写 keepalive 64;
  • proxy_http_version 1.1;
  • proxy_set_header Connection "";

这三行加完,后端连接复用起来,反代 QPS 通常能涨 30% 到 50%。代价是后端要能撑住长连接,老版本的 PHP-FPM 得确认 pm.max_requests 设置合理。

sendfile on、tcp_nopush on、tcp_nopush 配 sendfile 一起用,静态文件走内核零拷贝,大文件传输能省掉一次内存拷贝。tcp_nodelay 留给需要低延迟的小包场景,比如 API 接口。

缓存与压缩:省带宽还是省 CPU,得先算一笔账

gzip 开不开,取决于你的瓶颈在哪。开 gzip 能省 60% 到 70% 的传输体积,但每次请求都要现压,CPU 占用会上去。静态资源多的站,用 gzip_static on 直接读预压缩好的 .gz 文件,CPU 几乎不占,前提是构建时已经把文件压好。

gzip_comp_level 别往 9 调。1 到 5 之间收益递减很快,9 比 5 多压 3% 左右,CPU 却翻倍。我一般设 5,图片和视频本来就不该走 gzip,压了也白压。

proxy_cache 适合后端渲染慢的场景。缓存目录放 SSD 上,proxy_cache_path 的 levels 用 1:2 就够,keys_zone 给 10m 能存大概 8 万个 key。缓存时间按内容更新频率定,列表页 5 分钟、详情页 1 小时是常见组合。

这里有个取舍:缓存越激进,后端压力越小,但内容更新延迟越大。电商大促页面缓存 60 秒都可能出问题,博客站缓存一天也没人管。先想清楚能接受多长的延迟,再定 proxy_cache_valid。

如果站点跑在香港或者面向东南亚用户,带宽和线路对 Nginx 表现的影响比参数还大。香港大带宽服务器 III 是 E5-2630L*2 配 32G 内存、100M 带宽,月付 $223.50,跑高并发静态站或者反代层比较合适,香港大带宽服务器 III 这条线路对国内访问延迟通常在 30ms 上下。

调完怎么验证,别只看 QPS 数字

改完配置用 nginx -t 检查语法,再 reload,不要 restart,restart 会断掉现有连接。压测用 ab 或者 wrk,wrk 更接近真实并发。

看几个指标:

  • error.log 里有没有 accept() failed 或者 upstream timed out;
  • ss -s 看 TIME_WAIT 数量,几万条说明 keepalive 还没调对;
  • top 看 worker 进程 CPU 分布,如果只有一个进程吃满,说明 affinity 没生效。

QPS 涨了不代表没问题,得看 P99 延迟有没有跟着恶化。有时候 QPS 从 2000 涨到 8000,但 P99 从 50ms 变成 500ms,用户体验反而更差。

最后给个直接结论:静态站优先调 sendfile、gzip_static、keepalive_timeout;反代站重点在 upstream keepalive 和 proxy_cache;WebSocket 场景把 proxy_read_timeout 拉长,别让长连接被超时踢掉。核数少、内存小的机器别照搬 8 核配置,worker_connections 设太大会把内存吃光。