Nginx 生产环境高并发调优与常见排错实战指南
一、背景与目标
Nginx 作为生产环境中最常用的反向代理与静态资源服务器,在流量洪峰下常见的症状包括:502 Bad Gateway、504 Gateway Timeout、499 客户端断开、worker_connections 耗尽、Too many open files、TIME_WAIT 堆积等。本文从操作系统层、Nginx 配置层、反向代理层三个维度,给出一套可落地的调优与排错清单,并附上生产可用的配置片段。
二、操作系统层调优
Nginx 的性能上限首先受制于内核参数与文件句柄。建议在 /etc/sysctl.conf 中固化以下参数:
# 单进程可打开的文件句柄数
fs.file-max = 1000000
# 半连接队列与全连接队列
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# 加快 TIME_WAIT 回收,允许复用
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_tw_buckets = 60000
# 本地端口范围
net.ipv4.ip_local_port_range = 10240 65535
执行 sysctl -p 生效后,还需提高进程级限制(/etc/security/limits.conf):
* soft nofile 1000000
* hard nofile 1000000
nginx soft nofile 1000000
nginx hard nofile 1000000
三、Nginx 核心配置调优
以下配置分别位于 nginx.conf 的全局块、events 块与 http 块,是最影响高并发表现的一组参数:
# 全局块
worker_processes auto; # 与 CPU 核数对齐
worker_rlimit_nofile 1000000; # 每个 worker 可打开的句柄上限
events {
use epoll; # Linux 下最高效的事件模型
worker_connections 65535; # 单 worker 并发连接数
multi_accept on; # 一次唤醒接受多个新连接
accept_mutex off; # 高并发下关闭,避免惊群
}
http {
sendfile on; # 零拷贝发送静态文件
tcp_nopush on; # 与 sendfile 配合,合并小包
tcp_nodelay on; # 长连接下禁用 Nagle 算法
keepalive_timeout 65; # 长连接保持时间
keepalive_requests 10000; # 单连接最大请求数
types_hash_max_size 2048;
server_tokens off; # 隐藏版本号
gzip on;
gzip_min_length 1k;
gzip_comp_level 5;
gzip_types text/plain text/css application/json application/javascript text/xml image/svg+xml;
gzip_vary on;
client_max_body_size 50m; # 上传体积上限
client_body_buffer_size 256k;
large_client_header_buffers 4 32k;
}
四、反向代理与上游调优
反向代理场景下,缓冲区与上游长连接是两大性能关键点,配置示例如下:
upstream backend {
server 10.0.0.10:8080 max_fails=3 fail_timeout=10s;
server 10.0.0.11:8080 max_fails=3 fail_timeout=10s;
keepalive 128; # 复用上游长连接,降低握手开销
keepalive_requests 1000;
keepalive_timeout 60s;
}
server {
location /api/ {
proxy_http_version 1.1;
proxy_set_header Connection ""; # 关键:清空 Connection 才能复用上游长连接
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering on;
proxy_buffer_size 16k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
proxy_next_upstream error timeout http_502 http_503 http_504;
}
}
五、常见故障排查实战
1. 502 Bad Gateway
多为上游不可达或响应异常。排查顺序:
- 查看 error.log:tail -f /var/log/nginx/error.log,关注 connect() failed 与 upstream prematurely closed;
- 确认上游进程存活与端口监听:ss -lntp | grep 8080;
- 检查 SELinux / 防火墙是否拦截了 Nginx 到上游的连接。
2. 504 Gateway Timeout
上游处理超时。优先确认后端是否存在慢查询或慢接口,再调整 proxy_read_timeout,而不是盲目加大超时去掩盖问题。
3. 499 Client Closed Request
客户端在服务端返回前主动断开,常见于上游响应过慢导致用户或网关先行超时。应结合上游 RT 指标定位,而非修改 Nginx。
4. worker_connections are not enough
并发连接超过 worker_processes × worker_connections。需同步提升 worker_connections 与 worker_rlimit_nofile,并检查是否因上游未复用长连接而放大了连接数。
5. Too many open files
系统或进程句柄不足。用 cat /proc/$(pidof nginx | awk '{print $1}')/limits | grep files 验证 worker 实际限制,确保 limits.conf 与 worker_rlimit_nofile 一致。
6. TIME_WAIT 堆积
短连接频繁回收所致。启用 tcp_tw_reuse、引入上游 keepalive、开启客户端长连接均可显著缓解,可用 ss -s 观察 TIME-WAIT 数量。
六、监控与压测建议
开启 stub_status 掌握连接实时画像:
location = /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
# curl http://127.0.0.1/nginx_status
# Active connections: 291
# server accepts handled requests
# 16630948 16630948 31070465
压测推荐使用 wrk 或 ab,并同步采集 CPU、内存与连接数:
wrk -t8 -c1000 -d60s --latency http://your-domain/
七、总结
高并发调优的核心思路是:先解决内核与句柄等硬上限,再调 Nginx 事件模型与缓冲区等软参数,最后用监控与压测闭环验证。排错时坚持“看日志、看连接、看上游”的三板斧,避免用不断加大超时的方式掩盖根因。
- 点赞
- 收藏
- 关注作者
评论(0)