为什么你的 Nginx 默认配置需要调优?
刚装好的 Nginx,用起来似乎也没问题——直到某天流量突然上来了。
页面打开变慢、日志里频繁出现 502、服务器 CPU 没怎么涨但连接数已经爆了。翻一遍 nginx.conf,发现几乎所有参数都是出厂默认值:worker_processes 1、worker_connections 512、缓冲区全部注释着。
默认配置是 Nginx 面向”能用”做出的妥协,不是面向”好用”的承诺。一台 8 核 16G 的云服务器,如果 worker 还是 1,相当于 7 个核在睡觉;缓冲区太小,每个请求都会触发磁盘 I/O;keepalive 没开,TCP 握手反复重建。
这篇文章给你一份可直接落地的 Nginx 性能调优清单,覆盖 worker 进程、缓冲区、keepalive、Gzip 压缩四大模块,最后用压测数据验证优化效果。无论你是在 Hostease 全能型主机 上跑 WordPress,还是在自建服务器上部署微服务,这些调优思路都适用。
调优之前,先明确一个前提:Nginx 的性能瓶颈通常不在 CPU,而在连接管理和 I/O。理解这一点,才能抓住调优的重点。
第一章:worker_processes 与 worker_connections
初次接触 Nginx 配置?建议先阅读 VPS 使用教程,确保服务器基础环境就绪。
worker_processes 设多少合适?
worker_processes 控制 Nginx 启动多少个工作进程。每个 worker 是单线程的,进程之间互相独立,不存在锁竞争。这是 Nginx 高性能的基础架构设计。
调优原则很简单:
- CPU 密集型(静态文件服务):设为 CPU 核心数
- IO 密集型(反向代理、PHP-FPM):设为 CPU 核心数的 1.5~2 倍
- 偷懒方案:直接设
auto,让 Nginx 自动检测
# /etc/nginx/nginx.conf
worker_processes auto; # 自动匹配 CPU 核心数
worker_rlimit_nofile 65535; # 提高每个 worker 的文件描述符上限
worker_rlimit_nofile 这个参数经常被忽略。它设置每个 worker 进程能打开的最大文件描述符数量。如果你的服务器承载高并发,这个值必须大于 worker_connections,否则会报 too many open files 错误。
worker_connections 到底限制了什么?
每个 worker 能同时处理的连接数。它直接决定了 Nginx 的最大并发能力:
最大并发连接 = worker_processes × worker_connections
如果 Nginx 作为反向代理,每个客户端请求会占用 2 个连接(一个客户端到 Nginx,一个 Nginx 到后端),所以实际最大并发要除以 2。这意味着如果你的 worker_connections 设为 1024,实际只能同时服务 512 个客户端请求。
events {
worker_connections 10240; # 每个 worker 最多 10240 个连接
multi_accept on; # 一次 accept 多个新连接
use epoll; # Linux 下最高效的事件模型
}
multi_accept on 让 worker 一次 accept 多个新连接,而不是一次只 accept 一个。在高并发场景下,这个配置能显著减少连接建立的延迟。
use epoll 是 Linux 2.6+ 内核推荐的事件驱动模型,相比传统的 select 和 poll,epoll 在处理大量并发连接时性能优势明显。
别忘了检查系统层面的文件描述符限制:
# 查看当前限制
ulimit -n
# 临时修改
ulimit -n 65535
# 永久修改 /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
修改完 limits.conf 后,需要重新登录 SSH 会话才能生效。可以用 ulimit -n 验证是否已经更新。
第二章:缓冲区配置
缓冲区是 Nginx 性能调优中最容易被忽视、也最容易出效果的部分。合理的缓冲区配置能减少磁盘 I/O,提高请求处理速度。
客户端请求缓冲区
Nginx 接收客户端请求时,会把请求体暂存在缓冲区里。如果缓冲区放不下,才会写入临时文件——这意味着磁盘 I/O,而磁盘 I/O 是性能杀手。
http {
client_body_buffer_size 16k; # 请求体缓冲区,一般 8k~32k
client_header_buffer_size 1k; # 请求头缓冲区
large_client_header_buffers 4 8k; # 大请求头的缓冲区数量和单个大小
client_max_body_size 50m; # 允许的最大上传文件大小
}
client_body_buffer_size 的大小应该根据你的应用来定。如果你的网站有文件上传功能,可以适当增大到 128k 或 256k。但如果你的 API 请求体都很小(比如 JSON 数据),16k 就足够了。
large_client_header_buffers 用于处理较大的请求头,比如携带长 Cookie 或复杂 Authorization 头的请求。设置为 4 8k 意味着最多 4 个 8k 的缓冲区,总共 32k。
代理缓冲区(proxy_buffer)
Nginx 作为反向代理时,会先把后端响应读入缓冲区,再转发给客户端。缓冲区太小会导致频繁写入临时文件,这会显著增加延迟。
server {
location /api/ {
proxy_pass http://backend;
proxy_buffering on; # 开启代理缓冲
proxy_buffer_size 4k; # 第一部分响应(header)的缓冲区
proxy_buffers 8 16k; # 8 个 16k 的缓冲区
proxy_busy_buffers_size 32k; # 繁忙时可向客户端发送的缓冲区大小
proxy_temp_file_write_size 64k; # 临时文件写入块大小
}
}
proxy_buffer_size 专门用于接收后端响应的第一部分(通常是响应头)。这个值一般设为 4k 就够了,但如果你的后端返回很大的响应头(比如包含很多 Set-Cookie),可以增大到 8k 或 16k。
proxy_buffers 的格式是 数量 单个大小。总缓冲区大小 = 数量 × 单个大小。设置为 8 16k 意味着总共有 128k 的缓冲区来接收后端响应体。
FastCGI 缓冲区
如果你用 Nginx + PHP-FPM,FastCGI 缓冲区的配置直接影响 PHP 页面的响应速度:
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_buffering on;
fastcgi_buffer_size 16k;
fastcgi_buffers 16 16k;
fastcgi_busy_buffers_size 32k;
}
PHP 页面的响应通常比纯静态文件大得多,所以 FastCGI 缓冲区应该比 proxy_buffer 更大一些。16 16k 意味着总共 256k 的缓冲区,这对于大多数 PHP 应用(WordPress、Drupal 等)已经足够了。
如果你使用的是 Hostease 的主机产品,面板通常已经预设了合理的缓冲区默认值,但理解这些参数的含义仍然是必要的——因为你了解自己的应用,才能做出最适合的调整。
第三章:keepalive 超时与连接复用
如果你同时运行 WordPress 站点,WordPress 托管方案 中包含了 Nginx 与 PHP-FPM 的优化预设配置。
HTTP/1.0 默认每个请求都要新建 TCP 连接,HTTP/1.1 才有了 keep-alive 的概念。但 Nginx 默认的 keepalive 配置非常保守,调优空间很大。
客户端侧 keepalive
http {
keepalive_timeout 65s; # 客户端 keepalive 超时时间
keepalive_requests 1000; # 一个 keepalive 连接上最多处理多少个请求
}
keepalive_timeout设得太短,连接频繁断开重建;设得太长,会占用大量空闲连接,浪费服务器资源。keepalive_requests默认 1000,对大多数站点足够。如果你的页面有大量 AJAX 请求,可以适当增大到 2000 或 3000。
上游(upstream)keepalive
如果你的 Nginx 连接后端服务(PHP-FPM、Node.js、Java),一定要配置 upstream 的 keepalive:
upstream backend {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
keepalive 32; # 每个 worker 保持 32 个空闲长连接
keepalive_requests 1000;
keepalive_timeout 60s;
}
server {
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1; # 必须使用 HTTP/1.1
proxy_set_header Connection ""; # 清除 Connection: close
}
}
关键点:必须显式设置 proxy_http_version 1.1 和清除 Connection 头,否则 keepalive 不生效。这是因为 HTTP/1.0 默认是短连接,而 Nginx 的 proxy_set_header Connection "" 会告诉后端不要关闭连接。
keepalive 32 的含义是每个 worker 进程保持 32 个空闲长连接到后端。这个值应该根据你的后端服务能力和并发量来调整。如果后端是 PHP-FPM,建议设为 16~32;如果是 Node.js 或 Java 服务,可以设为 64~128。
第四章:Gzip 压缩、静态文件缓存与日志优化
启用 Gzip 压缩
开启 Gzip 可以大幅减少传输体积,尤其对 HTML、CSS、JS、JSON 效果显著:
http {
gzip on;
gzip_vary on; # 添加 Vary: Accept-Encoding 头
gzip_proxied any; # 代理请求也压缩
gzip_comp_level 4; # 压缩级别 1~9,推荐 4~6
gzip_min_length 256; # 小于 256 字节不压缩
gzip_types
text/plain
text/css
text/javascript
application/json
application/javascript
application/xml
application/rss+xml
image/svg+xml;
}
压缩级别(gzip_comp_level)从 1 到 9,级别越高压缩率越好但 CPU 开销也越大。测试表明,级别 4 和级别 9 的压缩率差距通常不超过 5%,但 CPU 差距可达 3~4 倍。建议设置为 4~6。
gzip_min_length 256 表示只有响应体大于 256 字节才压缩。小于这个大小的响应,压缩后可能反而更大(因为 gzip 有自己的头部开销)。
静态文件浏览器缓存
让浏览器缓存静态资源,可以大幅减少重复请求:
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|ttf)$ {
expires 30d; # 浏览器缓存 30 天
add_header Cache-Control "public, immutable";
access_log off; # 关闭静态文件的访问日志
}
immutable 告诉浏览器这个资源不会改变,不需要重新验证。对于带版本号的静态资源(如 style.abc123.css),这个配置特别有用。
日志优化
高频访问站点的日志写入本身就是一种 IO 开销。除了上面关闭静态资源日志,还可以调整日志缓冲:
access_log /var/log/nginx/access.log main buffer=32k flush=5s;
error_log /var/log/nginx/error.log warn;
buffer=32k 让日志先写入内存缓冲区,每 32k 或每 5 秒才刷一次磁盘,显著降低磁盘写入频率。对于日志量很大的站点,这个优化能减少 80% 以上的磁盘 I/O。
如果你需要临时禁用日志(比如在压测期间),可以设置 access_log off;,但生产环境建议保留日志,只是通过缓冲来优化写入性能。
第五章:压测验证与效果对比
调完参数要验证。推荐两个压测工具:wrk 和 ab(Apache Bench)。
使用 wrk 压测
# 安装
sudo apt install wrk
# 4 线程、1000 并发连接、持续 30 秒
wrk -t4 -c1000 -d30s http://your-server/
wrk 的优势是支持 Lua 脚本,可以模拟复杂的请求场景。如果你需要测试 POST 请求或带 Cookie 的场景,wrk 是更好的选择。
使用 ab 压测
# 发起 10000 个请求,并发 500
ab -n 10000 -c 500 http://your-server/
ab 是 Apache 自带的压测工具,简单易用,适合快速验证。但 ab 的并发能力有限,超过 1000 并发时结果可能不准确。
通过压测数据对比,你可以直观看到各项优化的实际效果。
更多更多运维技巧相关内容,可以参考 服务器运维指南 中的系列教程。
更多选购指南相关内容,可以参考 主机选购指南 中的系列教程。
总结清单
把本文的核心配置汇总成一张清单,供你直接对照修改:
- worker_processes:设为
auto或 CPU 核心数 - worker_connections:设为 10240+,同时修改系统 ulimit
- 事件模型:使用
epoll+multi_accept on - client_body_buffer_size:16k~32k
- proxy_buffers:8 个 16k(根据后端响应体大小调整)
- fastcgi_buffers:16 个 16k(PHP 站点)
- keepalive_timeout:65s
- upstream keepalive:32(配合 HTTP/1.1)
- Gzip 压缩:level 4,min_length 256
- 静态资源:expires 30d + access_log off
- 日志缓冲:buffer=32k flush=5s
- 压测验证:wrk 或 ab,对比 QPS 和延迟
行动建议:先用 nginx -T 导出当前完整配置,对照上面的清单逐项检查,每改一项就压测一次,记录效果。性能调优不是一次性工程,而是持续观察、持续迭代的过程。
想了解更多服务器运维与优化技巧,欢迎访问 Hostease 中文博客,我们持续分享建站与服务器管理的实用内容。