大带宽服务器Nginx调优:带宽吃到饱但CPU爆表?这10个坑新手必看

前言

大带宽服务器看着香,但很多新手一上来就把带宽跑满,结果CPU直接飙到100%,连接卡死,甚至丢包严重。问题往往出在Nginx默认配置和系统内核参数上。本文直接拆解10个高频陷阱,每个带复现场景+解决方案+验证命令,绝不废话。文中示例基于轻云互联的100Mbps大带宽独立服务器实测,带宽冗余够,但调优不到位照样崩。


1. Socket Backlog太小导致连接排队超时

现象:高并发下Nginx返回`502 Bad Gateway`或`Connection Refused`,`ss -lnt`显示`Recv-Q`堆积。

# 查看当前值
sysctl net.core.somaxconn
# 默认128,大带宽服务器至少改为65535
echo "net.core.somaxconn = 65535" >> /etc/sysctl.conf
sysctl -p

同时Nginx的`listen`指令必须同步增加backlog参数:

server {
    listen 80 backlog=65535;
    # 若用HTTPS
    listen 443 ssl backlog=65535;
}

验证curl -v --keepalive-time 10 http://your-ip/ 观察建立连接耗时是否<10ms。

2. TIME_WAIT过多耗尽端口——默认吃满内核表

场景:Nginx作反向代理或大量短连接时,`netstat -an | grep TIME_WAIT` 数量轻松破十万。内核端口范围默认32768-60999,只有~28000个,全被TIME_WAIT占满后新连接直接拒绝。

# 优化 sysctl
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.ip_local_port_range = 1024 65535
# 大带宽服务器建议缩小TIME_WAIT存活时间(生产需测试)
echo "30" > /proc/sys/net/ipv4/tcp_fin_timeout
# 或 sysctl
net.ipv4.tcp_fin_timeout = 30

Nginx端开启`reuseport` + 适当调整`worker_connections`:

events {
    worker_connections 65535;
    reuseport on;
}

3. 内核TCP缓冲区太小——高带宽下吞吐量减半

真实案例:轻云互联100Mbps服务器,默认`rmem_default`=212992,`tcp_rmem`="4096 87380 6291456",导致单流下载只到40Mbps。你需要按带宽计算缓冲区:

# 推荐值(以100Mbps*2倍BDP为例)
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 262144 16777216
net.ipv4.tcp_wmem = 4096 262144 16777216

配合Nginx开启sendfile和directio(对大文件效果明显):

sendfile on;
tcp_nopush on;
# 针对超过4MB的文件使用直接IO
directio 4m;
output_buffers 32 512k;

验证iperf3 -c server_ip -t 30 -w 2M 看看吞吐能否接近标称值。

4. worker进程与CPU绑定搞错——中断爆发

常见错误:所有worker共享所有CPU,高带宽下网卡中断集中在一个核,导致CPU软中断100%。

# 查看当前中断分布
cat /proc/interrupts | grep eth0
# 设置RPS(Receive Packet Steering)分散中断
echo "f" > /sys/class/net/eth0/queues/rx-0/rps_cpus
# 更狠:使用SMP affinity(需确认驱动支持)
# 先检查网卡支持的队列数
ethtool -l eth0

Nginx的`worker_cpu_affinity`也要跟着绑:

worker_processes auto;
worker_cpu_affinity auto; # 自动绑定到不同CPU

5. 超时配置太刻板——大带宽下慢连接导致worker死循环

:默认`keepalive_timeout`=75s,`proxy_read_timeout`=60s。大带宽服务器常对接上游慢源(如数据库),一旦上游响应慢,worker被占满,新请求排队。

# 合理压缩超时,释放worker
keepalive_timeout 10;
keepalive_requests 100;
proxy_connect_timeout 5s;
proxy_read_timeout 10s;
proxy_send_timeout 10s;

同时开启upstream的`keepalive`池减少连接建立开销:

upstream backend {
    server 127.0.0.1:8080;
    keepalive 256;
}
location / {
    proxy_http_version 1.1;
    proxy_set_header Connection "";
}

6. 访问日志刷盘锁死磁盘IO

症状:`iostat -x 1`显示磁盘util 100%,但带宽只有30Mbps。访问日志默认每行写一次,大带宽下每秒钟几十万行,直接撑爆。

# 关闭无用日志(如静态资源)
location ~* \.(jpg|png|mp4)$ {
    access_log off;
}
# 日志批量写入
access_log /var/log/nginx/access.log main buffer=32k flush=5s;

生产环境建议将日志写入内存盘/dev/shm:

access_log /dev/shm/access.log main buffer=64k;

7. gzip静态文件导致的CPU过载

误区:对所有资源开启gzip。大带宽服务器客户端带宽充足,但CPU弱(比如低端VPS),压缩反而增加延迟。应只对文本类型压缩,且级别设为2:

gzip on;
gzip_min_length 1024;
gzip_comp_level 2;
gzip_types text/plain text/css application/json application/javascript text/xml;
# 不压缩图片/视频
gzip_disable "msie6";

对于静态文件,推荐预压缩:`gzip_static on`配合`gunzip`,省去Nginx实时压缩。

8. 文件描述符限制炸了

翻车现场:`ulimit -n`默认1024,Nginx最大连接=work_connections * worker_processes,大带宽下轻松破万,然后报`too many open files`。

# 修改 /etc/security/limits.conf
*               soft    nofile          1048576
*               hard    nofile          1048576
# 然后配置Nginx
worker_rlimit_nofile 1048576;

别忘了重启服务并确认:cat /proc/$(cat /var/run/nginx.pid)/limits | grep 'no file'

9. proxy_buffer过小吞掉上游响应

表现:反向代理返回不完整页面或报`upstream sent too big header`。大带宽服务器常用作中间层代理,默认`proxy_buffer_size` 4k根本不够。

proxy_buffering on;
proxy_buffer_size 16k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
proxy_temp_path /var/tmp/nginx 1 2;
# 如果上游是fastcgi,同理
fastcgi_buffer_size 16k;
fastcgi_buffers 8 16k;

10. 忽略状态锁——Nginx access/error log vs syslog

冷门坑:日志写入到`/var/log`的文件系统(如ext4)在高并发下会产生inode锁竞争。轻云互联服务器上实测,将日志改道到syslog可降低CPU占用3-5%。

# 安装rsyslog
# Nginx配置
access_log syslog:server=unix:/dev/log,facility=local7,tag=nginx_access,severity=info main;
error_log syslog:server=unix:/dev/log,facility=local6,tag=nginx_error;

配合syslog开启异步写入:rsyslog.conf中`$WorkDirectory /var/spool/rsyslog`,增加`main_queue_size 50000`。


总结

大带宽服务器不是买来就自动跑满的,90%的新手翻车都源于上面10个点。把这套配置跑一遍,配合nginx-tuning-cheatsheet脚本,基本能榨干硬件性能。如果你懒,直接上轻云互联的优化镜像,出厂自带内核+应用层调优,但你至少得知道该往哪看。