Nginx 调优:从内核参数到缓存链路,哪几步真能提速

2026-10-08 08:04 1003 次浏览

站点流量涨到某个量级之后,Nginx 的配置文件就成了每天都要翻一遍的东西。CPU 使用率突然冲到 80%,或者压测时连接数上不去,多数人第一反应是去改 worker_connections,改完发现没什么变化。真正的问题通常藏在更靠前的地方——进程模型对不对,系统给进程的资源上限够不够。这篇按我平时排查的顺序讲,从进程和连接数开始,一路走到缓存和压缩,每一步都说明白改它值不值。

worker 进程和连接数,先看这两个数再谈别的

Nginx 处理请求靠的是 worker 进程,每个进程能接多少连接由 worker_connections 决定。这两项配得不对,后面所有优化都是白费。我一般先看 worker_processes 设的是不是 auto,让 Nginx 自己按 CPU 核数决定,比手工写死数字更省事。

连接数要算的是总上限,不是单个进程的上限。一个 4 核机器,worker_connections 设 1024,理论上能撑四千多个并发连接,但还要减去反向代理占用的连接对。前端做代理的机器,实际能承受的并发往往只有理论值的一半。

  • worker_processes 用 auto,别写死 2 或 4
  • worker_connections 从 1024 起步,代理场景按一半估算
  • worker_rlimit_nofile 要跟系统的 ulimit -n 对齐,不然会撞上文件描述符上限

ulimit 这一层我见过不少漏掉的配置。Nginx 报错日志里出现 too many open files,基本就是这里没对齐。改完记得让 systemd 重新加载,光改配置文件不重启不生效。

sendfile 和 keepalive,省的是 CPU 也是内存

静态文件多的站点,sendfile 打开之后数据直接从内核缓冲区发出去,不用在用户态和内核态之间来回拷。这一项在默认配置里通常是开的,但有些发行版打包的版本会关掉,值得确认一遍。

keepalive 这块要分两个方向看。客户端到 Nginx 的 keepalive_timeout 设太长,空闲连接会占着内存不放;设太短,客户端频繁重连又浪费握手开销。我一般给 15 到 30 秒,具体看访客的翻页间隔。另一头是 Nginx 到后端应用的 keepalive,这个连接池不配好,后端每次请求都要重新建连,延迟会明显上去。

后端连接池的 keepalive 数量不用设太大,几十个就够大多数场景用。设多了反而会占住后端的连接配额。这点我没法给一个通用数字,得看后端能接多少。

gzip 和缓存,最值得花时间的地方

压缩和缓存是收益最直接的两块,也是最容易配错的。gzip 开太狠,CPU 会先扛不住;开太浅,省下的带宽又不够看。

gzip_comp_level 我通常给 4 到 6。再往上加,压缩率提升有限,CPU 开销却涨得快。gzip_types 要明确列出来,默认只压 text/html,CSS 和 JS 不写进去等于没压。图片和视频别放进来,格式本身已经压过,再压一遍纯属浪费。

缓存这块,静态资源用 expires 和 add_header Cache-Control 配合,把图片、字体这类不常变的东西设成一年。HTML 页面单独设短一点,不然用户看不到更新。动态接口能不能缓存,要看业务允不允许,这点得自己判断。

如果机器本身跑在带宽吃紧的线路上,压缩和缓存带来的收益会比调内核参数更明显。像 香港大带宽(20M)高速云服务器 这类配置,8 核 8G 加 20M 带宽,适合把静态资源分发和动态请求分开处理,压出来的带宽能实打实省下来。

什么时候该换机器,而不是继续改配置

配置调到一定程度就会遇到天花板。单机 Nginx 能扛的并发有上限,超过之后再怎么调参数都只是把崩溃往后推。判断要不要换机器,我一般看两个信号:一是 CPU 长期在 70% 以上,二是带宽跑满的时间占比超过三成。

这两个信号同时出现,说明瓶颈已经不在软件层。这时候继续折腾 worker_connections 或者 gzip 级别,收益很小。把静态资源和动态接口拆到两台机器上,或者直接换一台带宽更宽的独立服务器,效果更直接。

香港机房的机器延迟低,适合面向国内用户的站点。带宽给到 20M 以上的话,静态资源分发基本够用。真要跑大流量,香港宿主机(大母鸡)① 这种 44 核 88 线程、64G 内存的配置,可以在一台机器上跑多个站点,省掉不少横向扩展的麻烦。

总结一下取舍:并发没到瓶颈之前,把 worker 进程、连接数、压缩和缓存这几项配好,多数站点能稳定跑很久。CPU 和带宽同时吃紧的时候,别在配置文件里继续找答案,换硬件比调参数划算。