Nginx 调优别乱改配置:先看清 worker、连接数与超时这三处
机房带宽从 100M 升到 G 口,机器换成 E5-2683v4 双路 64G,页面还是偶尔卡一下。登上去看 nginx -t 一切正常,top 里 CPU 没打满,带宽也没跑满,但并发一上两千就开始有超时。多数人第一反应是加内存,其实 Nginx 的性能瓶颈常常不在硬件上,而在几个默认值上。下面按我平时排查的顺序说,从进程模型到内核参数,一条条对。
worker_processes 和 worker_connections 不是随便写个数字
Nginx 默认 worker_processes 1,这在单核小机器上够用,4 核以上就浪费了。我一般直接写 worker_processes auto,让它自己数 CPU 核心。真正容易被忽略的是 worker_connections,默认 512,意味着单个 worker 最多同时处理 512 个连接。4 个 worker 理论上是 2048 并发,但反代场景下客户端占一个连接、到后端又占一个,实际能承接的请求数要砍掉一半。
把 worker_connections 调到 10240,同时在 events 块里加上 multi_accept on,让一个 worker 一次接多个新连接。代价是每个连接都要占内存,worker_connections 开太大而内存不够,反而会触发 OOM。2G 内存的机器我一般控制在 4096 以内,4G 以上才敢上 10240。
调完连接数还得看系统层。文件描述符上限如果还是默认的 1024,Nginx 起不来那么多连接,日志里会报 too many open files。在 /etc/security/limits.conf 里给 nginx 用户加上 nofile 65535,再确认 systemd 的 LimitNOFILE 也同步改了,否则重启后又回到默认值。这一步很多人改完没生效,就是因为漏了 systemd 的覆盖。
超时参数调不好,连接会被白白占住
keepalive_timeout 默认 75 秒,对长连接是好事,但如果你前面挂了负载均衡,空闲连接会一直占着 worker 名额。我通常降到 30 秒左右,配合 keepalive_requests 1000 限制单连接最多处理多少个请求,防止某个客户端长期占用。
client_header_timeout 和 client_body_timeout 默认各 60 秒。慢速攻击就是靠这个拖住连接不放,把这两个降到 10 到 15 秒,正常用户上传大文件基本不受影响。send_timeout 也可以从 60 秒压到 20 秒,避免后端慢响应时连接堆积。
这里有个取舍:调太短,弱网用户上传会中途断掉;调太长,攻击流量会把连接池吃满。我一般先按 15 秒配,观察一周 access log 里的 408 数量,再决定要不要放宽。
gzip、缓存和 sendfile 才是省带宽的那部分
开了 gzip 之后 HTML、CSS、JSON 这些文本能压到原来的三成左右,但图片和视频别开,压不动还白耗 CPU。gzip_comp_level 我一般用 5,再往上压缩率提升有限,CPU 占用却明显上升。gzip_min_length 设成 1k,太小的响应压缩反而更慢。
静态资源交给 sendfile on 和 tcp_nopush on 处理,走内核零拷贝,比在用户态读一遍再写一遍快不少。缓存头用 expires 控制,图片、JS 这类不常变的资源设 30 天,HTML 设几分钟甚至不缓存,避免用户拿到旧页面。
如果后端是动态应用,proxy_cache 能挡掉大量重复请求。缓存目录放在 SSD 上,proxy_cache_valid 按状态码分别设置,200 的页面缓存 10 分钟,404 缓存 1 分钟就够。缓存命中率上不去的时候,先看 key 里是不是带了会变的参数,比如时间戳或随机数,那等于没缓存。
什么时候该换机器,而不是继续调参数
参数调到底也有上限。如果单机 QPS 已经压到 CPU 满载,或者带宽跑满还丢包,再优化 Nginx 意义不大。这时候要考虑的是把静态资源和动态请求拆开,静态走大带宽机器,动态留在应用服务器。
像 香港大带宽服务器 XXIV 这种 Platinum 8168 双路 64G 配 G 口的配置,适合把图片、视频这类吃带宽的内容单独放一台,前端 Nginx 只做转发和缓存,应用服务器的压力会小很多。预算有限的话,西雅图那台 E5-2620 32G 100M 也能承担中等流量的静态分发。
判断标准很简单:调完 worker 和超时参数后,如果 ss -s 里 TIME_WAIT 数量长期在几万以上,或者 Nginx 的 active connections 一直贴着 worker_connections 上限,那就是连接处理能力到顶了,该拆服务或换配置。反过来,如果连接数不高但响应慢,问题多半在后端应用或数据库,不在 Nginx 这一层。
先把 worker_processes、worker_connections、nofile 三处对齐,再压超时,最后开 gzip 和缓存。这套顺序走下来,2 核 4G 的机器撑住三五千并发是常见的,再往上就得看业务模型和带宽了。