FORMA

性能调优基础

性能调优的目标是:用有限的资源,支撑更高的并发、更快的响应、更稳的服务。下面按优化维度,逐一拆解原理和配置要诀。

一、工作进程优化

1. Worker 数量

原理
每个 Worker 是一个单线程事件循环,绑定到一个 CPU 核心上可以避免上下文切换和 CPU 缓存失效。Worker 数量超过核心数会引起争抢,小于核心数则不能充分利用多核能力。

配置

nginx
# 推荐自动匹配
worker_processes auto;

# 亦可手动指定,如 4 核机器
worker_processes 4;

可查看 /proc/cpuinfo 确认物理核心数,一般无需超过该值(除非存在大量阻塞 I/O,但 Nginx 设计初衷就是非阻塞,极少需要超配)。

2. CPU 亲和性(worker_cpu_affinity

原理
将每个 Worker 进程绑定到指定的 CPU 核心,减少进程在不同核心间迁移导致的缓存失效,并提高 CPU 利用率。注意,现代调度器通常做得足够好,此配置已非必需,但在高负载实时系统或特殊 NUMA 环境下可能仍有收益。

配置示例

nginx
worker_processes 4;
# 四核心,一 Worker 绑定一核心
worker_cpu_affinity 0001 0010 0100 1000;

如无明确测试依据,使用默认(不绑定)即可。

二、连接与超时微调

1. 最大并发与连接数

原理
每个 Worker 能打开的文件描述符数受系统限制(ulimit -n),Nginx 最大并发连接数 ≈ worker_processes × worker_connections。但每个客户端会占用 2 个左右连接(如正向代理),且系统还要保留文件描述符给静态文件、日志等,需留有余量。

配置

nginx
events {
    worker_connections  4096;
    # 控制同时接受多个新连接
    multi_accept on;
}

同时要修改系统限制:编辑 /etc/security/limits.conf 增加 nginx soft nofile 65535,并确保 nginx.confworker_rlimit_nofile 设置为同等或更高:

nginx
worker_rlimit_nofile 65535;

2. Keepalive 参数

原理
HTTP 长连接能复用 TCP 连接,减少握手开销,提升前端访问和后端代理的性能。

  • keepalive_timeout:服务器端保持连接的超时,过长会堆积空闲连接消耗资源。
  • keepalive_requests:单连接上允许的最大请求数,超过后关闭连接,以均衡连接复用与资源释放。

配置

nginx
http {
    keepalive_timeout 60 60;   # 长连接 60 秒
    keepalive_requests 1000;   # 单个连接最多服务1000个请求

    # 对上游的长连接(反向代理时尤为重要)
    upstream backend {
        server 10.0.0.1:80;
        keepalive 32;          # 保留的空闲 keepalive 连接数
    }
    server {
        location / {
            proxy_http_version 1.1;
            proxy_set_header Connection "";  # 清除 Connection 头以启用 keepalive
            proxy_pass http://backend;
        }
    }
}

开启上游 keepalive 可显著减少与后端的 TCP 握手和 TIME_WAIT,大幅提升代理能力。

三、高效传输

1. sendfiletcp_nopushtcp_nodelay

原理

  • sendfile:调用 sendfile() 系统调用,将文件数据直接从内核缓冲区拷贝到网络栈,绕过用户态,实现零拷贝,极大提升静态文件传输效率。
  • tcp_nopush:在开启 sendfile 后生效,将 HTTP 响应头与数据包合并发送,减少 TCP 分段,提升网络利用率。适合大文件。
  • tcp_nodelay:关闭 Nagle 算法,让小包立即发送,不等待合并,减少延迟。适合需要实时交互的请求(如 API、WebSocket)。

配置

nginx
http {
    sendfile      on;          # 零拷贝
    tcp_nopush    on;          # 配合 sendfile,减少包数量
    tcp_nodelay   on;          # 对 keepalive 连接,降低延迟
}

三者在同一连接上可并存,内核会根据实际情况选择行为。

四、启用 Gzip 压缩

原理
压缩响应体,节省带宽、加速传输,但消耗 CPU。需在压缩比率、压缩文件类型和 CPU 开销间取得平衡。

配置

nginx
http {
    gzip on;
    gzip_vary on;                     # 添加 Vary: Accept-Encoding 头
    gzip_comp_level 5;               # 压缩级别 1-9,推荐 5-6
    gzip_min_length 256;             # 过小文件不压缩
    gzip_proxied any;                # 对代理请求也进行压缩判断
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/javascript
        application/xml+rss
        application/json
        image/svg+xml
        application/x-font-ttf
        font/opentype;
    gzip_disable "MSIE [1-6]\.";     # 对远古 IE 禁用
}

注意gzip_comp_level 6 以上 CPU 开销急剧上升而压缩率收益递减,保持 5 左右即可。静态小文件可预先压缩为 .gz 文件并结合 gzip_static 模块直接发送,极大节省 CPU。

五、缓存配置

1. 浏览器缓存(expires / Cache-Control

原理
通过设置响应头,让浏览器或中间代理缓存静态资源,消除重复请求,减少服务端压力和网络流量。

配置

nginx
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff2)$ {
    expires 1y;                        # 一年后过期
    add_header Cache-Control "public, immutable";
    add_header Pragma public;
    # 若文件名无版本号,可用短过期时间
}
location ~ \.html$ {
    expires -1;                        # 不缓存
}

细节expires 指令会自动生成 ExpiresCache-Control: max-age。对于带哈希的构建产物,设置长期缓存并配合不可变标记 immutable

2. 代理缓存(proxy_cache

原理
Nginx 将上游服务器的响应缓存到磁盘(或内存),后续相同请求直接从缓存返回,大幅度减轻后端负载和响应时间。适用于静态 API 响应、页面片段等。

配置步骤

nginx
http {
    # 定义缓存路径和规则
    proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m
                     max_size=10g inactive=60m use_temp_path=off;

    server {
        location /api/ {
            proxy_cache my_cache;
            proxy_cache_key "$scheme$request_method$host$request_uri";
            proxy_cache_valid 200 302 10m;
            proxy_cache_valid 404      1m;
            proxy_cache_use_stale error timeout updating;
            # 支持条件请求,让客户端可验证缓存
            proxy_cache_revalidate on;
            proxy_pass http://backend;
        }
    }
}
  • keys_zone 设定共享内存区域名称和大小,存放缓存元数据。
  • levels=1:2 配置两级子目录,避免单目录文件数过多。
  • inactive 规定时间内访问则清除缓存。
  • proxy_cache_use_stale 在后端异常时能交付过期缓存,保障可用性。

3. 快速缓存(FastCGI 缓存等)

原理与代理缓存类似,针对 PHP 等 FastCGI 后端:

nginx
fastcgi_cache_path /data/nginx/fcgicache levels=1:2 keys_zone=fcgi:10m max_size=2g;
fastcgi_cache fcgi;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_valid 200 10m;

同样适用于 uwsgi_cachescgi_cache,对动态内容可以显著加速。

调优准则总结

  1. 先测量,后调优——使用 nginx -V 检查编译参数,用访问日志记录 $request_time$upstream_response_time 定位瓶颈。
  2. 根据角色分层优化
    • 纯静态资源:重 sendfile + tcp_nopush + gzip_static + expires。
    • 反向代理:keepalive 后端连接池 + proxy_cache + 合适的超时。
    • 全栈站点:动静分离,动态部分走缓存或加速。
  3. 压力测试验证:每项调优后使用 wrkabvegeta 等工具压测,对比 QPS、响应时间分布和错误率。

把这些优化项逐一落实并测试,你的 Nginx 就能真正地“快、稳、省”。

参考文献

资料说明
nginx 文档官方
运维导读学习路径

Series

nginx

5 / 7