Nginx 调优别急着改配置,先把这几处瓶颈找出来

2026-10-11 08:19 1007 次浏览

不少人拿到一台新服务器,装完 Nginx 第一件事就是去网上抄一份「优化配置」,把 worker_processes 写成 auto,再随手加一堆 gzip 和缓存指令,跑起来发现 QPS 还是上不去。问题不在配置抄得对不对,而在于没先搞清楚这台机器的瓶颈究竟在哪。CPU 吃满和磁盘 IO 打满,要改的东西完全是两码事。

下面按「先定位、再调参数、最后看场景」的顺序讲,每一节都对应一个具体动作,改完能立刻用 ab 或 wrk 验证。

先看 worker 进程和连接数对不对得上

Nginx 处理请求靠的是 worker 进程,每个 worker 能同时接住的连接数由 worker_connections 决定。默认值通常是 512,这个数字在 4 核以上的机器上明显偏低。

理论最大并发连接数的算法是 worker_processes 乘以 worker_connections。假设 8 核机器,worker_processes 设成 8,worker_connections 设成 10240,那并发上限就是 81920。但别只看这个乘积,系统层面的文件描述符限制(ulimit -n)如果还是 1024,Nginx 会在日志里报「too many open files」,实际并发根本到不了配置值。

所以顺序是这样的:先把 ulimit -n 提到 65535,再调 worker_connections。我一般会把 worker_rlimit_nofile 也显式写进配置,避免重启后又被系统默认值压回去。

  • worker_processes:物理核数即可,不用开超线程数
  • worker_connections:1024 起步,静态站点可以到 10240
  • worker_rlimit_nofile:跟 ulimit -n 保持一致,比如 65535

改完记得 nginx -t 检查语法再 reload,直接 restart 会丢连接。

keepalive 和 gzip,开与不开的代价

keepalive_timeout 默认 75 秒,对长连接场景够用。但如果你的站点全是短请求,比如 API 网关,keepalive 开太长反而占着 worker 连接不放。我一般把 keepalive_timeout 压到 15 到 30 秒,keepalive_requests 设成 1000,让单个连接多跑几个请求再断开。

gzip 是个容易踩坑的地方。开了 gzip 确实省带宽,但 CPU 会多一份压缩开销。文本类响应(HTML、CSS、JS)压缩比能到 70% 以上,值得开;图片和视频已经压过了,再 gzip 一次纯属浪费 CPU。gzip_comp_level 别设太高,4 到 6 之间性价比最好,设到 9 压缩率提升有限,CPU 却要多花不少。

另外 gzip_min_length 设成 1k,太小的响应压缩后可能反而变大。

静态资源交给缓存,动态请求才走后端

这是最容易被忽略、但收益最大的一步。如果站点有大量图片、CSS 这类静态文件,让 Nginx 直接从内存或磁盘返回,比每次转发给后端快一个数量级。

open_file_cache 这组指令能把文件句柄和元数据缓存在内存里,减少反复 stat 系统调用。配置大致是这样:open_file_cache max=10000 inactive=30s,再配合 open_file_cache_valid 和 open_file_cache_min_uses。对静态站来说,开了这组参数后磁盘 IO 压力会明显下降。

expires 头也要设,告诉浏览器静态资源可以缓存多久。图片和字体设 30 天,CSS 和 JS 设 7 天,配合文件名加 hash 做版本控制。

如果后端是 PHP 或 Node,proxy_cache 能把动态页面的渲染结果缓存住。这部分配置复杂一些,适合访问量大、内容更新不频繁的场景。

调完这些,一台 8 核 16G 的机器跑纯静态站,单机 3000 QPS 通常没问题。但要注意,如果业务本身是动态请求多、数据库查询重,再怎么调 Nginx 也救不了,瓶颈在后端不在接入层。

需要更大带宽或独立资源跑高并发接入层时,可以看看 香港大带宽服务器 XXVI,E5-2683v4 双路配 64G 内存和 100M 带宽,跑 Nginx 前置节点比较合适;如果业务在美区,硅谷裸机云 VIII 的 100M 带宽月付 $119 起步,适合中小流量站点先跑起来看真实负载。