Nginx 性能调优
Worker 进程配置
nginx.conf 全局配置
# worker 数量 = CPU 核心数
worker_processes auto;
# 绑定 CPU 亲和性(减少上下文切换)
worker_cpu_affinity auto;
events {
# 每个 worker 的最大连接数
worker_connections 10240;
# Linux 下推荐 epoll
use epoll;
# 允许一次性接受所有新连接
multi_accept on;
}
提示
worker_connections × worker_processes = Nginx 可处理的最大并发连接数。作为反向代理时,每个客户端连接实际占用 2 个连接(客户端→Nginx + Nginx→后端)。
文件传输优化
http {
# sendfile: 内核态直接传输文件,避免用户态拷贝
sendfile on;
# 配合 sendfile,在一个 TCP 包中发送 HTTP 响应头和文件内容
tcp_nopush on;
# 小数据包立即发送(关闭 Nagle 算法)
tcp_nodelay on;
# 保持连接超时
keepalive_timeout 65;
keepalive_requests 1000;
}
Gzip 压缩
http {
gzip on;
gzip_min_length 1k; # 小于 1KB 不压缩
gzip_comp_level 4; # 压缩级别 1-9,推荐 4-6
gzip_types
text/plain
text/css
text/javascript
application/json
application/javascript
image/svg+xml;
gzip_vary on; # 添加 Vary: Accept-Encoding
gzip_static on; # 优先使用预压缩的 .gz 文件
}
代理缓存
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=app_cache:20m
max_size=2g inactive=60m use_temp_path=off;
server {
location /api/ {
proxy_pass http://backend;
proxy_cache app_cache;
proxy_cache_valid 200 10m; # 200 响应缓存 10 分钟
proxy_cache_valid 404 1m;
proxy_cache_key "$scheme$request_method$host$request_uri";
add_header X-Cache-Status $upstream_cache_status;
}
}
}
静态资源优化
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
# 打开文件缓存(减少磁盘 IO)
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
}
关键性能参数速查
| 参数 | 推荐值 | 说明 |
|---|---|---|
worker_processes | auto | 等于 CPU 核心数 |
worker_connections | 10240 | 高并发场景可提高 |
keepalive_timeout | 65s | 长连接超时 |
gzip_comp_level | 4-6 | 压缩率与 CPU 的平衡点 |
proxy_cache_valid | 按场景 | API 短缓存,静态资源长缓存 |
常见面试问题
Q1: Nginx 为什么能支撑高并发?
答案:
- 事件驱动 + 异步非阻塞:基于 epoll,单个 worker 可处理数千并发连接
- 多 worker 进程:充分利用多核 CPU,worker 间无锁竞争
- 零拷贝:sendfile 内核态传输,避免用户态缓冲区拷贝
- 内存池:预分配内存块,减少 malloc/free 开销
Q2: sendfile、tcp_nopush、tcp_nodelay 三者的关系?
答案:
- sendfile:内核态直接发送文件,跳过用户态拷贝
- tcp_nopush(配合 sendfile):将响应头和文件内容合并到尽可能少的 TCP 包中发送(Nagle 聚合)
- tcp_nodelay:小数据包立即发送,不等待聚合
看似矛盾但实际协同:tcp_nopush 在发送大块文件时聚合,最后一个包时切换为 tcp_nodelay 立即发送,兼顾吞吐量和延迟。