为什么你的 Nginx 还需要调优?
很多站长在部署完 Nginx(高性能 HTTP 和反向代理服务器)之后,直接使用默认配置就开始跑业务。默认配置在低流量场景下确实能用,但当并发连接数突破几百甚至上千时,你会发现响应时间明显变长,甚至出现 502 错误。
这篇文章将帮你解决这个问题。我们整理了一份 Nginx 性能调优清单,聚焦三个核心维度:worker 进程配置、缓冲区设置和 keepalive(长连接)优化。每个配置项都会给出具体参数、适用场景和验证方法,而不是泛泛而谈。
如果你正在使用 Hostease 的 VPS 主机 或 独立服务器,这些调优技巧同样适用。下面我们逐项展开。
worker 进程:并发能力的根基
worker 进程是 Nginx 处理请求的核心单元。配置不当,再多的优化也是白搭。
worker_processes 设置
worker_processes 控制 Nginx 启动多少个工作进程。常见误区是把它设成一个固定值(比如 2 或 4),而不考虑服务器实际的 CPU 核心数。
推荐做法是直接设为 auto,让 Nginx 自动检测 CPU 核心数并启动对应数量的 worker:
worker_processes auto;
在一台 4 核的 VPS(虚拟专用服务器)上,auto 会启动 4 个 worker 进程,每个进程绑定一个 CPU 核心,避免进程间的 CPU 争抢。你可以通过 worker_cpu_affinity 进一步指定绑定关系:
worker_cpu_affinity auto;
worker_connections 单进程并发上限
每个 worker 进程能同时处理的最大连接数由 worker_connections 决定。默认值通常是 512 或 1024,对于中等流量的站点来说偏保守。
实际配置时需要考虑两个因素:一是服务器的文件描述符上限(ulimit -n),二是业务的连接模式。如果页面平均会建立 3-5 个并发连接(HTTP/1.1 多路复用),那么 worker_connections 应该设为预期并发用户数的 3-5 倍。
events {
worker_connections 4096;
multi_accept on;
use epoll;
}
multi_accept on 让每个 worker 一次 accept 多个新连接,减少系统调用次数。use epoll 是 Linux 下最高效的 I/O 多路复用方式,2.6 以上内核都支持。
配置完成后,你可以用以下命令验证 worker 进程数和连接数:
# 查看 worker 进程数
ps aux | grep nginx | grep worker | wc -l
# 查看当前连接数
ss -s | grep estab
worker_rlimit_nofile 文件描述符限制
操作系统对每个进程能打开的文件描述符数量有限制,而 Nginx 的每个连接都会占用一个文件描述符。如果这个值太低,高并发时 Nginx 会报 too many open files 错误。
建议把 worker_rlimit_nofile 设为 worker_connections 的 2 倍以上,留出余量给日志文件、缓存文件等:
worker_rlimit_nofile 8192;
同时需要修改系统的 ulimit 设置。编辑 /etc/security/limits.conf,添加:
* soft nofile 65535
* hard nofile 65535
修改后重新登录或重启 Nginx 生效。
缓冲区配置:减少磁盘 I/O 的关键
缓冲区(buffer)是 Nginx 在内存中暂存请求和响应数据的区域。配置合理的缓冲区能显著减少磁盘读写次数,提升静态文件和代理请求的处理速度。
client_body_buffer_size 请求体缓冲
这个参数控制 Nginx 缓存 POST 请求体的内存大小。如果请求体超过这个值,Nginx 会把数据写入临时文件,触发磁盘 I/O。
对于普通表单提交(不含文件上传),16KB 通常够用。如果有文件上传场景,需要配合 client_max_body_size 一起调整:
client_body_buffer_size 16k;
client_max_body_size 50m;
proxy_buffer_size 代理响应头缓冲
当你用 Nginx 做反向代理(如代理到后端的 Node.js 或 PHP-FPM)时,proxy_buffer_size 控制响应头的缓冲大小。默认的 4KB 或 8KB 在大多数场景下够用,但如果后端返回的响应头较大(比如包含多个 Set-Cookie),可能需要调大:
proxy_buffer_size 8k;
proxy_buffers 代理响应体缓冲
proxy_buffers 控制代理响应体的缓冲区数量和单个缓冲区大小。设置过小会导致 Nginx 频繁写磁盘临时文件,设置过大则浪费内存。
推荐配置:
proxy_buffers 8 16k;
proxy_buffer_size 8k;
这里 8 16k 表示 8 个 16KB 的缓冲区,总共 128KB。对于大多数动态页面来说够用。如果你的页面平均响应体较大(比如返回大量 JSON 数据),可以调整为 8 32k。
静态文件缓存 open_file_cache
对于静态资源(CSS、JS、图片),Nginx 每次请求都会检查文件是否存在、读取文件元信息。open_file_cache 可以把这些信息缓存在内存中,避免重复的文件系统调用:
open_file_cache max=10000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
max=10000:最多缓存 10000 个文件的元信息inactive=20s:20 秒内没被访问的缓存条目会被清除open_file_cache_valid 30s:每 30 秒重新验证一次缓存的有效性open_file_cache_min_uses 2:至少被访问 2 次才会被缓存
keepalive 连接:复用 TCP 连接降低延迟
keepalive(长连接)是 HTTP/1.1 的默认行为,允许客户端在同一 TCP 连接上发送多个请求,避免每次请求都经历 TCP 三次握手的开销。
upstream keepalive 后端长连接
当 Nginx 作为反向代理时,与后端服务器(upstream)之间的连接默认是短连接——每个请求结束后连接就关闭了。在高并发场景下,频繁的 TCP 建立和销毁会消耗大量系统资源。
通过 keepalive 指令可以启用与 upstream 的长连接:
upstream backend {
server 127.0.0.1:8080;
keepalive 32;
keepalive_requests 1000;
keepalive_timeout 60s;
}
server {
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
关键点有两个:一是 proxy_http_version 1.1(keepalive 需要 HTTP/1.1),二是 proxy_set_header Connection ""(清除客户端发来的 Connection: close 头)。
keepalive 32 表示每个 worker 进程保持 32 个到 upstream 的空闲长连接。这个值不宜设得太大,否则会占用后端服务器的连接数。一般设为 upstream 服务器数量的 2-4 倍即可。
HTTP keepalive_timeout 客户端长连接
keepalive_timeout 控制与客户端之间的长连接保持时间。默认值通常是 65-75 秒,对于大多数场景来说偏长。
如果用户打开页面后快速离开,这条连接会一直占用直到超时。适当缩短这个值可以释放连接资源:
keepalive_timeout 30s;
keepalive_requests 100;
keepalive_timeout 30s:30 秒内没有新请求就关闭连接keepalive_requests 100:单个连接最多处理 100 个请求后关闭
对于 API 服务场景,可以适当延长到 60 秒,减少客户端频繁建立连接的开销。对于静态资源站点,30 秒通常足够。
一个完整的调优配置示例
把上面的配置整合到一起,这是一个适合 4 核 VPS 的 Nginx 调优模板:
# worker 进程
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 8192;
events {
worker_connections 4096;
multi_accept on;
use epoll;
}
http {
# 缓冲区
client_body_buffer_size 16k;
client_max_body_size 50m;
proxy_buffer_size 8k;
proxy_buffers 8 16k;
# 静态文件缓存
open_file_cache max=10000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# keepalive
keepalive_timeout 30s;
keepalive_requests 100;
upstream backend {
server 127.0.0.1:8080;
keepalive 32;
keepalive_requests 1000;
keepalive_timeout 60s;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /static/ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}
}
配置完成后,用 nginx -t 检查语法是否正确,再用 nginx -s reload 平滑重载。重载不会中断现有连接,新配置会在下一个请求中生效。
总结与下一步行动
Nginx 性能调优不是一次性工作,而是一个持续迭代的过程。我们建议你按以下步骤操作:
- 先用默认配置跑一段时间,通过
nginx -V确认当前编译参数和模块 - 根据服务器配置(CPU 核心数、内存大小)调整 worker 参数,观察并发连接数变化
- 逐步调整缓冲区和 keepalive 参数,每次只改一两个配置项,用压测工具(如 wrk 或 ab)验证效果
- 监控 Nginx 的 access log 和 error log,关注 502、504 错误和
too many open files警告
如果你正在使用 VPS 主机,可以直接在控制面板中修改 Nginx 配置。遇到配置问题也可以参考 服务器优化指南 获取更多运维技巧。
可以考虑把这份清单保存下来,每次部署新服务器时对照检查。性能优化是一个渐进的过程,从最影响业务的那个瓶颈开始调,效果往往最明显。