Nginx 凭借事件驱动的异步架构,在高并发场景下表现出色。但默认配置并非针对高负载优化的,在搬瓦工 VPS 上部署网站时,合理调整 worker 进程、连接数、keepalive、Gzip 压缩与缓存策略,能在相同硬件条件下显著提升并发能力和响应速度。本文给出系统性的 Nginx 调优方案,并提供可直接使用的配置片段。

本文要点

  • worker 进程数应与 CPU 核心数一致,或设 auto
  • 提升每个 worker 的连接数上限,配合系统 ulimit
  • keepalive 减少连接建立开销,Gzip 压缩减少传输量
  • 静态文件添加长期缓存头,减少重复请求

Worker 进程配置

Nginx 主进程(master)负责管理,worker 进程处理实际请求。worker 数量应与 CPU 核心数匹配:

# /etc/nginx/nginx.conf
worker_processes auto;           # 自动等于 CPU 核心数
worker_rlimit_nofile 65535;      # worker 进程可打开的文件数

events {
    worker_connections 2048;     # 每个 worker 最大并发连接数
    use epoll;                   # Linux 高效 I/O 事件模型
    multi_accept on;             # 一次尽可能多地接受新连接
}

worker_connections 的理解

worker_connections 是每个 worker 进程的连接上限,总并发数 = worker_processes × worker_connections。设置时还需保证系统 ulimit -nworker_rlimit_nofile,否则实际效果受限。

HTTP 核心参数

http {
    # keepalive:复用 TCP 连接
    keepalive_timeout 65;        # 保持连接的超时时间(秒)
    keepalive_requests 1000;     # 单个连接最多处理的请求数

    # 发送优化
    sendfile on;                 # 零拷贝传文件,减少 CPU 开销
    tcp_nopush on;               # 与 sendfile 配合,减少网络包数量
    tcp_nodelay on;              # 实时数据禁用 Nagle 算法

    # 超时设置
    client_header_timeout 15;    # 读取请求头超时
    client_body_timeout 30;      # 读取请求体超时
    send_timeout 30;             # 响应发送超时

    # 请求大小限制
    client_max_body_size 20m;    # 上传文件大小上限(根据业务调整)
    client_body_buffer_size 128k;
}

Gzip 压缩配置

Gzip 能将 HTML/CSS/JS 等文本文件压缩 60%~80%,大幅减少传输量:

http {
    gzip on;
    gzip_min_length 1024;        # 小于 1KB 的文件不压缩(压缩收益低)
    gzip_comp_level 5;           # 压缩级别 1~9,5 是速度与压缩率的平衡点
    gzip_vary on;                # 告知缓存代理区分压缩与非压缩版本
    gzip_types
        text/plain
        text/css
        text/javascript
        application/javascript
        application/json
        application/xml
        image/svg+xml;
    # 注意:图片/PDF 等已压缩格式不要加入 gzip_types
}

静态文件缓存

为静态资源设置浏览器缓存,减少重复请求到服务器:

server {
    # 图片、字体、媒体文件:长期缓存
    location ~* \.(jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # CSS/JS:带版本号时可长期缓存
    location ~* \.(css|js)$ {
        expires 7d;
        add_header Cache-Control "public";
    }

    # API 接口:禁止缓存
    location /api/ {
        add_header Cache-Control "no-store, no-cache";
    }
}

连接与安全限速

# 限制单 IP 并发连接数和请求频率,防止滥用
http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    limit_req_zone  $binary_remote_addr zone=req:10m rate=30r/s;
}

server {
    limit_conn addr 50;          # 单 IP 最多 50 个并发连接
    limit_req zone=req burst=60 nodelay;  # 突发 60 个,超出延迟处理
}
配置项优化效果适用场景
worker_processes auto充分利用多核所有场景
gzip on减少 60%~80% 文本传输Web 服务
keepalive_timeout 65减少握手开销高并发
expires 30d(静态文件)减少重复请求静态资源丰富的站点
limit_req防止突发流量打垮公开 API/表单

调优后验证方法

修改配置后用 nginx -t 验证语法,再用 systemctl reload nginx 平滑重载(不中断现有连接)。可用 ab -n 1000 -c 100 http://你的域名/ 做简单并发测试,对比调优前后的吞吐量变化。

小结

  • worker_processes auto + worker_connections 2048 充分利用多核
  • Gzip 压缩对文本类资源效果显著,图片勿加
  • 静态文件设长期 expires,减少不必要的重复请求
  • limit_conn/limit_req 防止单 IP 滥用打垮服务器
  • 每次改配置用 nginx -t 验证,reload 平滑上线

常见问题

Nginx 内存占用突然升高,怎么排查?

ps aux | grep nginx 查看各 worker 进程内存,再用 nginx -V 确认是否开启了过多模块。通常内存增长是连接数暴增导致,可配合 limit_conn 控制单 IP 并发。

开启 Gzip 后,响应时间反而变长了?

Gzip 压缩消耗 CPU,对小文件(<1 KB)压缩收益低但 CPU 开销不低。请确认 gzip_min_length 已设合理值(推荐 1024),并检查 gzip_comp_level 是否设得太高(7~9 级 CPU 开销大)。

nginx -t 显示语法正确,但 reload 后配置没有生效?

reload 只对新连接生效,已有的长连接还走旧配置。如果需要立即全部生效,可用 systemctl restart nginx(会短暂中断现有连接)。