Nginx调优别只盯参数表:从连接队列到缓存策略的实战思路
很多Nginx优化文章只罗列参数,却不讲为什么调、调完看什么。本文从连接队列、文件缓存、代理缓存和日志四个方向,讲清生产环境里真正影响体验的环节。
搜Nginx优化,出来的大多是一张参数对照表。但生产环境里,真正卡住性能的往往不是某个参数没设对,而是连接队列溢出、缓存没开、日志写太猛这些具体问题。这篇文章换个角度,从现象倒推该调哪里。
连接被拒?先看队列和文件描述符
用户反馈偶发502或连接超时,第一反应可能是后端挂了,但有时候是Nginx的accept队列满了。系统层面的somaxconn和Nginx的backlog要匹配,文件描述符上限也要放开。这些不改,worker_connections设再大也接不住突发流量。
- 检查net.core.somaxconn和net.ipv4.tcp_max_syn_backlog。
- Nginx里listen 80 backlog=2048; 与系统值对齐。
- 确认worker_rlimit_nofile和系统ulimit一致。
改完用ss -lnt看Send-Q和Recv-Q,如果队列经常非零,说明还有积压。
静态文件慢,不一定是磁盘的锅
Nginx自带open_file_cache,能把文件句柄和元数据缓存起来,减少重复的stat调用。对图片、CSS、JS多的站点,开启后响应时间会有可感知的下降。同时sendfile和tcp_nopush配合使用,能减少小包发送。
- open_file_cache max=10000 inactive=30s; 按文件数量调。
- open_file_cache_valid 60s; 缓存有效期。
- sendfile on; tcp_nopush on; 静态资源传输更高效。
如果站点托管在带宽充足的物理服务器上,比如台湾大带宽服务器 IV,静态资源的传输瓶颈会小很多,缓存策略的收益也更直接。
代理缓存用对了,能救后端一命
动态站点前面加一层Nginx代理缓存,把不常变的接口或页面缓存几十秒,后端压力能降一大截。关键是要区分哪些能缓存、哪些不能。带用户登录态的请求、POST请求、带Set-Cookie的响应,默认都不该缓存。
- proxy_cache_path指定缓存目录和内存区。
- 用proxy_cache_key把URL、方法和必要头组合成key。
- 通过proxy_cache_bypass和proxy_no_cache控制绕开缓存的场景。
- 加X-Cache-Status响应头,方便排查命中率。
缓存时间别拍脑袋,先观察接口的数据更新频率,再决定TTL。短则5秒,长则几分钟,命中率上去了再慢慢调。
日志写太猛,也会拖慢服务
访问日志默认每条请求都写磁盘,高并发下IO压力不小。可以按需关闭部分日志、开启buffer、或者用条件日志只记录异常状态码。错误日志级别从debug调到warn或error,能减少大量无用写入。
- access_log ... buffer=64k flush=5s; 批量写入。
- 用map定义条件,只记录4xx和5xx。
- 错误日志级别设为error或warn。
日志策略调整后,对比磁盘IO和Nginx的CPU占用,通常能看到变化。调优不是一次性的,每次业务变化后都值得回头看一眼这些基础项。