CentOS 出现 backlog 过多的定位与处理
一、先判断属于哪类 backlog
- 若日志出现 audit: backlog limit exceeded,这是 Linux 审计服务 auditd 的缓冲区队列溢出,和 TCP 连接队列不同。先用命令查看当前审计缓冲与规则:auditctl -s;临时放大缓冲:auditctl -b 8192;永久生效在 /etc/audit/audit.rules 中使用 -b 设置,再重启 auditd。注意每个审计缓冲约 8970 字节,例如将 backlog_limit 设为 10000 将额外占用约 87 MiB 内存。生产环境不建议直接关闭审计,应合理调大缓冲或优化审计规则。
二、TCP 监听队列与半连接队列的排查与优化
- 快速定位
- 查看各监听端口的当前排队情况:ss -lnt(关注 Recv-Q,接近或达到 Send-Q 表示队列趋满)。
- 查看全量连接状态分布:netstat -an | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’。
- 检查内核与应用的队列上限:cat /proc/sys/net/core/somaxconn;cat /proc/sys/net/ipv4/tcp_max_syn_backlog;同时核对应用配置(如 Nginx 的 listen … backlog、Tomcat 的 acceptCount)。
- 内核参数优化(示例为合理起步值,按业务压测微调)
- 提升全系统监听队列上限:echo 4096 > /proc/sys/net/core/somaxconn;持久化到 /etc/sysctl.conf:net.core.somaxconn = 4096。
- 提升半连接(SYN)队列上限:echo 8192 > /proc/sys/net/ipv4/tcp_max_syn_backlog;持久化:net.ipv4.tcp_max_syn_backlog = 8192。
- 提升网卡接收队列:echo 16384 > /proc/sys/net/core/netdev_max_backlog;持久化:net.core.netdev_max_backlog = 16384。
- 开启 SYN Cookies 抵御少量 SYN Flood:echo 1 > /proc/sys/net/ipv4/tcp_syncookies;持久化:net.ipv4.tcp_syncookies = 1。
- 应用层需同步放大 backlog(否则仅改内核无效):如 Nginx 配置 listen 80 backlog 1024; Tomcat 配置 acceptCount 等。
- 使配置生效:sysctl -p。
三、若主要是 TIME_WAIT 或 CLOSE_WAIT 堆积
- 大量 TIME_WAIT
- 开启端口重用与时间控制:net.ipv4.tcp_tw_reuse = 1;net.ipv4.tcp_fin_timeout = 30;必要时启用 net.ipv4.tcp_tw_recycle = 1(注意:在 NAT/负载均衡或多主机环境下开启 tcp_tw_recycle 可能有副作用,需谨慎评估)。
- 适度放宽本地端口范围:net.ipv4.ip_local_port_range = 1024 65000。
- 控制最大 TIME_WAIT 数量:net.ipv4.tcp_max_tw_buckets = 200000(超过将被快速清理并打印警告)。
- 大量 CLOSE_WAIT
- 这通常是应用未按协议正确关闭连接(被动关闭后未调用 close),内核参数无法根治,应从应用/中间件(如 Tomcat、Nginx upstream、客户端 SDK)排查连接释放逻辑与超时设置。
四、资源与文件句柄的配套优化
- 文件句柄与进程数
- 提高系统总文件句柄上限:echo 6553560 > /proc/sys/fs/file-max;持久化:fs.file-max = 6553560。
- 提高进程可打开文件数:在 /etc/security/limits.conf 增加 * soft nofile 327680 与 * hard nofile 327680;如需按用户细化可在 /etc/security/limits.d/ 下新增配置。
- TCP 内存与端口范围
- 为 TCP 连接分配合理内存(以 4GB 内存示例):net.ipv4.tcp_mem = 196608 262144 393216;8GB 可设为 524288 699050 1048576。
- 放宽本地端口范围(配合高并发出站连接):net.ipv4.ip_local_port_range = 1024 65000。
五、最小改动的一键式起步方案(示例值,压测后再调)
- 内核与网络
- net.core.somaxconn = 4096
- net.ipv4.tcp_max_syn_backlog = 8192
- net.core.netdev_max_backlog = 16384
- net.ipv4.tcp_syncookies = 1
- net.ipv4.tcp_tw_reuse = 1
- net.ipv4.tcp_fin_timeout = 30
- net.ipv4.tcp_max_tw_buckets = 200000
- net.ipv4.ip_local_port_range = 1024 65000
- fs.file-max = 6553560
- 应用层
- Nginx:listen 80 backlog 1024;
- Tomcat:acceptCount 调至 1000~5000 区间并配合 connectionTimeout 合理设置。
- 使配置生效:sysctl -p;随后用 ss -lnt 与 netstat 状态分布观察队列与连接变化,持续压测微调。