Nginx 调优别急着改配置:先把瓶颈找准,再动 worker 和缓存
不少人接手一台服务器,第一件事就是上网搜一份 Nginx 优化配置,把 worker_processes、worker_connections、各种 timeout 一股脑复制进去,重启,然后觉得安心了。真到流量涨起来,页面该慢还是慢,502 该出现还是出现。问题不在参数抄得对不对,在于根本没确认瓶颈在哪一步。CPU 跑满了、连接数打满了、后端响应慢、磁盘 IO 堵住,这四种情况的解法完全不一样,用同一套参数去套,等于闭着眼吃药。
先分清是 Nginx 慢,还是后端慢
判断方法很直接:看 Nginx 的错误日志和 access 日志里的 upstream_response_time。如果这个值本身就很高,说明时间花在后端,Nginx 再怎么调都是白搭。
我做排查时一般先看两处。一是 worker 进程的 CPU 占用,如果单个 worker 跑满而其他核闲着,多半是 worker_processes 设成了 1。二是 连接状态,用 ss -s 看 TIME_WAIT 和 ESTABLISHED 的数量,连接数接近上限时新请求会被直接丢掉。
这两步十分钟能做完,却决定了后面所有调整的方向。跳过它,后面全是猜测。
worker 数量与连接数,按机器核数算而不是按感觉设
worker_processes 设成 auto 通常就够了,它等于 CPU 核数。4 核机器就是 4 个 worker,8 核就是 8 个。设得比核数多没有收益,反而增加上下文切换。
真正容易踩坑的是 worker_connections。它决定每个 worker 能同时处理多少连接,但这个数字不是「越大越好」。
- 操作系统层面的文件描述符上限要先放开,否则 Nginx 设了 65535,内核只给 1024,照样卡在 1024
- 反向代理场景下,一个客户端请求会占用两条连接:一条对客户端,一条对后端,实际并发要除以 2
按我的经验,一台 2 核 4G 的机器,worker_connections 设 10240 已经足够,理论并发在 2 万连接上下,但真实瓶颈往往先出现在内存和后端,而不是这个数字。与其把参数堆到 65535,不如先确认内核的 somaxconn 和 ulimit -n 有没有同步调上去。
keepalive 与缓存:省下的到底是哪笔钱
这一节值得多花点篇幅,因为它是多数人调优时最容易开错的地方。
对客户端开启 keepalive_timeout,收益是省掉重复的 TCP 三次握手。静态资源多的站点,把它设到 30 到 65 秒比较常见。代价是每个空闲连接仍然占着内存和文件描述符,连接数特别多的场景下反而会拖累。
对后端开启 upstream keepalive,收益明显得多。默认情况下 Nginx 每转发一个请求就要和后端新建一条 TCP 连接,后端如果还要处理 TLS,这笔开销不小。配置里加上 keepalive 32 并配合 proxy_http_version 1.1 和 proxy_set_header Connection "",能省掉大量重复握手。
代理缓存则是另一笔账。开 proxy_cache 能挡住重复的回源请求,但会带来两个成本:一是磁盘空间,缓存写满后频繁淘汰反而增加 IO;二是内容一致性,动态接口缓存了不该缓存的东西,用户看到的是旧数据。我一般只对图片、CSS、JS 这类静态资源开缓存,接口层不开。
如果后端本身响应就慢,缓存只是把慢的部分藏起来,用户第一次访问还是要等。这种情况该做的是查后端,不是加缓存层。
什么时候该考虑换机器,而不是继续调参数
调优有天花板。当 CPU 长期跑在 80% 以上、内存频繁触发 swap、磁盘 IO 已经打满的时候,继续改配置只是把问题往后推。
判断换机的时机,我通常看两个信号。一是高峰期 worker 进程持续满载超过十几分钟,二是请求排队导致的延迟已经影响到业务。到了这一步,加核数或者换一台独享资源的物理机,比在软件层反复折腾划算。
如果业务本身是面向香港或亚太用户的站点,机器放到离用户近的机房,比任何参数调整都更能降低延迟。比如 香港服务器4,E5-2650 双路、32G 内存、20M 带宽,月付 144 美元,适合中小型站点的反向代理和静态资源分发;流量更大、需要更高带宽的,可以看 香港自营物理服务器(100M),双路 E5-2450L 共 16 核 32 线程、32G 内存、100M 带宽,月付 3600 元,属于独享资源,不会和别的用户抢 CPU。这两档的差别不在参数,在资源是不是你自己的。
回到配置本身。把 worker_processes 设成 auto,确认 ulimit 和 somaxconn 跟上,后端开 keepalive,静态资源开缓存,这四步能解决大部分常见问题。剩下的,先看日志再动手,别让参数调整变成一种心理安慰。