温馨提示×

linux backlog满了会怎样

小樊
43
2026-09-17 13:55:54
栏目: 智能运维

在 Linux 网络编程和系统中,backlog 通常指 listen() 系统调用中指定的连接队列长度,或者更广义地指 内核中用于存放“已完成三次握手但尚未被应用 accept”的队列(accept 队列)
backlog 满了(更准确说是 accept 队列满了),会发生以下情况:


一、TCP 连接层面会发生什么

1. 已完成连接(ESTABLISHED)进不了 accept 队列

  • 客户端完成三次握手
  • 内核想把这个连接放进 accept 队列
  • 但队列已满 → 连接无法交付给应用层

2. 半连接队列(SYN 队列)也可能受影响

  • 如果 /proc/sys/net/ipv4/tcp_syncookies = 0
    → 新的 SYN 可能被 直接丢弃
  • 如果开启 syncookies
    → 不会丢 SYN,但依然无法建立最终连接

3. 客户端表现

客户端通常会看到:

  • connect() 超时
  • Connection timed out
  • 或偶尔 Connection reset by peer(取决于内核版本和配置)

二、典型现象总结

现象 说明
新连接连不上 accept 队列满,应用没及时 accept
CPU 不高但连接失败 不是计算瓶颈,是队列阻塞
旧连接正常 已 accept 的连接不受影响
压力测试失败 并发连接数上不去

三、常见原因

  1. 应用 accept 太慢
    • 单线程、阻塞式 accept
    • 业务逻辑耗时
  2. backlog 设置太小
    • listen(fd, 5) 在高并发下明显不够
  3. 瞬时并发太高
    • 秒杀、突发流量
  4. 线程池耗尽
    • 连接进来但没人处理

四、Linux 实际队列机制(重要)

现代 Linux 中:

  • backlog 参数 不是精确值
  • 实际队列长度 ≈ min(backlog, somaxconn)
  • somaxconn 默认通常是 1284096

查看:

cat /proc/sys/net/core/somaxconn

修改:

sysctl -w net.core.somaxconn=65535

五、如何排查

# 查看 Listen 队列溢出
netstat -s | grep listen

# 或
ss -lnt

关注:

  • Recv-Q 接近 Send-Q
  • TCPBacklogDrop 增加

六、解决方式

✅ 增大 backlog

listen(fd, 1024);

✅ 增大 somaxconn
✅ 使用 多线程 / 非阻塞 + epoll
✅ 快速 accept,再丢给线程池处理
✅ 开启 syncookies(防 SYN 攻击)


一句话总结

Linux backlog 满了,新连接进不来,客户端表现为连接超时或失败,但已建立的连接不受影响。

如果你愿意,我可以结合 具体语言(C / Java / Go / Nginx)内核版本 给你更精确的解释。

0