CentOS backlog 快速处置与根治
一、先判定 backlog 类型与证据
- 区分两类 backlog:
- TCP 全连接队列(accept 队列):已完成三次握手、等待进程 accept() 的连接。
- 审计 backlog(auditd):内核审计事件缓冲区溢出,常见日志为“audit: backlog limit exceeded”。
- 快速检查命令与判读要点:
- 查看全连接队列:ss -lnt | grep :端口,LISTEN 行中 Recv-Q 为当前排队连接数,Send-Q 为队列上限(即 min(somaxconn, 应用 backlog))。示例:Send-Q 为 128 表示队列上限 128。持续增长的 Recv-Q 且 Send-Q 固定,多为应用 accept 不及时或队列偏小。溢出时可用 netstat -s | grep -i “listen” 观察溢出计数是否递增。必要时将 tcp_abort_on_overflow=1,客户端若出现大量 “connection reset by peer”,通常说明全连接队列曾满。
- 查看半连接队列(SYN 队列)压力:netstat -s | grep -E “SYNs|accept” 观察 SYN 相关计数与 accept 队列溢出;压测可用 hping3 --tcp -p 80 -c 1000 或 wrk 制造连接洪峰复现问题。
- 审计 backlog:执行 auditctl -s 查看 backlog_limit 与当前状态;若日志出现 “audit: backlog limit exceeded”,说明审计缓冲区不足。
二、TCP 全连接队列满的应急与根治
- 应急(立即生效,先止血):
- 提升内核全连接队列上限:sysctl -w net.core.somaxconn=4096(或 2048/8192 视内存与负载而定)。
- 让应用使用更大的 backlog:例如 Nginx 在 listen 指令中设置 backlog=4096;修改后需重启应用以重新调用 listen()。
- 观察是否仍溢出:ss -lnt 看 Send-Q 是否变大、Recv-Q 是否不再逼近上限;netstat -s 的溢出计数是否停止增长。
- 根治(同步做,避免反复):
- 确保全连接队列上限 = min(somaxconn, 应用 backlog),两者需同步调大;必要时将 tcp_abort_on_overflow 设为 0(默认,更利于应对突发流量),仅在确认队列长期满溢再考虑设为 1 快速失败。
- 降低应用 accept 延迟:检查 worker 进程/线程数、是否阻塞在磁盘 I/O 或锁竞争,确保能及时从队列取走连接。
- 若半连接也吃紧(SYN 洪峰/慢速攻击),同步调大 net.ipv4.tcp_max_syn_backlog 并开启 net.ipv4.tcp_syncookies=1 做兜底。
三、TCP 半连接队列满的应急与根治
- 应急:
- 开启或调高 tcp_syncookies:sysctl -w net.ipv4.tcp_syncookies=1,在半连接队列满时启用 cookie 机制减轻 SYN 丢弃。
- 提升半连接队列上限:sysctl -w net.ipv4.tcp_max_syn_backlog=8192(或更高,视并发与内存而定)。
- 根治:
- 排查连接洪峰与异常源(压测、攻击、重试风暴),必要时在边界启用限流/清洗。
- 结合全连接队列一起优化:应用尽快 accept,内核与应用的队列需匹配,避免“前端能收、后端接不住”。
四、auditd backlog 超限的应急与根治
- 应急:
- 临时放大审计缓冲区:sysctl -w kernel.audit_backlog_limit=8192(或 16384/32768)。
- 根治与容量核算:
- 单个审计缓冲区约 8970 字节;默认 backlog_limit=320 约占用 2.7 MiB。例如设为 10000 约需 87 MiB 内存。计算公式:占用内存 ≈ backlog_limit × 8970 字节。根据内存余量合理设置,并持久化到 /etc/sysctl.conf。
- 如非必须,避免完全关闭审计(生产环境不建议)。优化规则、减少无用审计事件,也能缓解压力。
五、可直接复制的推荐参数与验证步骤
- 推荐最小改动集(示例值,按内存与业务调优):
- TCP 全连接队列:sysctl -w net.core.somaxconn=4096
- TCP 半连接队列:sysctl -w net.ipv4.tcp_max_syn_backlog=8192;sysctl -w net.ipv4.tcp_syncookies=1
- 队列溢出行为:sysctl -w net.ipv4.tcp_abort_on_overflow=0
- 持久化:将上述参数写入 /etc/sysctl.conf 并执行 sysctl -p
- 应用层:将 Nginx 等监听 backlog 提升到与 somaxconn 匹配的值(如 4096),并重启服务
- 验证步骤(1–2 分钟完成):
- ss -lnt | grep :端口:确认 Send-Q 已提升到目标值,Recv-Q 在峰值时不再逼近上限
- netstat -s | grep -i “listen|syn”:观察溢出计数是否停止增长
- 如曾设置 tcp_abort_on_overflow=1,临时切回 0 并恢复业务观察客户端错误是否减少
- 若是 auditd:auditctl -s 确认 backlog_limit 与当前状态,确认日志不再出现 “backlog limit exceeded”