深色模式
Nginx 性能调优
摘要:Nginx 调优围绕三条主线:worker 进程与 CPU 亲和、单进程可打开的连接数、以及操作系统层面的 fd 与端口范围限制。本文给出一份可直接落地的配置基线,并教你用压测工具验证调优前后差异。
适用环境
bash
nproc # CPU 核数,决定 worker_processes
ulimit -n # 当前 shell 的 fd 上限
cat /proc/sys/net/core/somaxconn
cat /proc/sys/net/ipv4/ip_local_port_range
uname -r1
2
3
4
5
2
3
4
5
操作步骤
1. 设置 worker 与连接数
nginx
# /etc/nginx/nginx.conf 顶部
user nginx;
worker_processes auto; # 自动等于 CPU 核数
worker_cpu_affinity auto; # 进程绑核,减少上下文切换
worker_rlimit_nofile 65535; # 必须 >= worker_connections * 2 左右
events {
use epoll; # Linux 下最高效
worker_connections 10240; # 单 worker 最大连接数
multi_accept on; # 一次 accept 多个新连接
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
2. 打开高效传输与压缩
nginx
http {
sendfile on;
tcp_nopush on; # 配合 sendfile,减少小包
tcp_nodelay on; # keepalive 场景降低延迟
keepalive_timeout 65;
keepalive_requests 1000; # 单连接最大请求数,防长连接泄漏
gzip on;
gzip_comp_level 5;
gzip_min_length 1024; # 太小的文件压缩反而变慢
gzip_types text/plain text/css application/json application/javascript;
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
3. 调整内核参数
bash
sudo tee /etc/sysctl.d/99-nginx.conf <<'EOF'
net.core.somaxconn = 65535
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.core.netdev_max_backlog = 65535
fs.file-max = 200000
EOF
sudo sysctl --system1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
4. 放开 systemd 的 fd 限制(否则 worker_rlimit_nofile 不生效)
bash
sudo mkdir -p /etc/systemd/system/nginx.service.d
sudo tee /etc/systemd/system/nginx.service.d/override.conf <<'EOF'
[Service]
LimitNOFILE=65535
EOF
sudo systemctl daemon-reload
sudo systemctl restart nginx1
2
3
4
5
6
7
2
3
4
5
6
7
DANGER
worker_connections 受 ulimit -n 硬限制约束:只改配置不改 LimitNOFILE 与 worker_rlimit_nofile,日志里会刷 worker_connections are more than open file resource limit,实际并发仍然上不去。
5. 压测对比
bash
# 安装压测工具(任选其一)
sudo yum install -y httpd-tools # 提供 ab
# 或 sudo apt-get install -y wrk
ab -n 100000 -c 1000 -k http://127.0.0.1/healthz
# -n 总请求数 -c 并发数 -k 启用 keepalive1
2
3
4
5
6
2
3
4
5
6
验证
bash
# 1) 配置语法与生效值
sudo nginx -t
sudo nginx -T | grep -E 'worker_processes|worker_connections'
# 2) 进程实际 fd 上限
pid=$(pgrep -o nginx); cat /proc/$pid/limits | grep 'open files'
# 3) 压测后统计状态码分布(应无 5xx、无非预期 499)
sudo awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
# 4) 观察 TIME_WAIT 是否可控
ss -s | grep -i 'timewait'1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
常见坑
WARNING
worker_processes 并非越多越好。设为 CPU 核数即可,超过核数反而增加上下文切换开销;虚拟化环境注意看的是实际可用 vCPU。
WARNING
压测时 502 增多先查上游,而不是继续加 Nginx 并发。很可能是 proxy_connect_timeout 过短或后端连接池打满。
DANGER
gzip_comp_level 调到 9 会显著吃 CPU,收益却很小;且对已压缩的(图片、视频、zip)内容开启 gzip 只会白白消耗 CPU。用 gzip_types 明确限定文本类型。