温馨提示×

linux backlog溢出怎么办

小樊
41
2026-09-17 13:46:54
栏目: 智能运维

在 Linux 网络编程和系统中,“backlog 溢出”通常指 TCP 监听队列(accept queue)满,导致新连接被丢弃或重传,表现为连接失败、延迟高、SYN 被丢等。下面按「定位 → 原因 → 解决」来说明。


一、先确认是不是 backlog 溢出

1. 查看连接队列溢出

netstat -s | grep -i listen

cat /proc/net/netstat | grep ListenOverflows

重点关注:

  • ListenOverflows:监听队列溢出次数
  • ListenDrops:监听被丢弃次数

如果这两个值持续增长,就是 backlog 溢出。

2. 查看当前队列长度

ss -lnt

示例:

State  Recv-Q Send-Q Local Address:Port
LISTEN 129    128    :::8080
  • Recv-Q:当前已完成握手的连接数
  • Send-Q:backlog 上限(min(应用 backlog, somaxconn))

如果 Recv-Q == Send-Q,说明队列已满。


二、backlog 由什么决定(关键)

实际 backlog 上限是:

min(应用 listen(backlog), net.core.somaxconn)

常见默认值

  • 应用层:listen(fd, 128)(很多框架默认)
  • 内核:net.core.somaxconn = 128

所以 即使你设了 1024,也可能被 128 限制


三、解决方案(按优先级)

✅ 1. 调大 somaxconn(最常用)

sysctl -w net.core.somaxconn=65535

持久化:

echo "net.core.somaxconn=65535" >> /etc/sysctl.conf
sysctl -p

✅ 2. 应用层 listen backlog 调大

  • Nginx:
listen 8080 backlog=65535;
  • Java:
serverSock.bind(new InetSocketAddress(port), 65535);
  • Go:
net.ListenConfig{Backlog: 65535}
  • Node.js:
server.listen(port, () => {}, 65535);

⚠️ 必须 应用 + 内核同时调大 才有效。


✅ 3. 调大半连接队列(SYN 队列)

如果 SYN 很多:

sysctl -w net.ipv4.tcp_max_syn_backlog=65535

✅ 4. 启用 SYN Cookie(防 SYN Flood)

sysctl -w net.ipv4.tcp_syncookies=1

注意:SYN Cookie 开启后,半连接队列基本无限,但不保证 TCP 选项性能最优


✅ 5. 加快 accept(根本解决)

backlog 溢出通常不是“太小”,而是:

  • 业务处理慢
  • 单线程 accept
  • 线程池不够

优化方向:

  • 多进程 / 多线程 accept
  • 非阻塞 + epoll
  • 连接与业务解耦(先 accept,再异步处理)

✅ 6. 限流 & 防护

如果是攻击:

  • 限制单 IP 连接数
  • 使用 iptables / nftables
  • 上 LB / 网关层缓冲

四、一次完整推荐配置(高并发服务)

net.core.somaxconn=65535
net.ipv4.tcp_max_syn_backlog=65535
net.ipv4.tcp_syncookies=1

应用 listen backlog ≥ 65535


五、常见误区

❌ 只改应用 backlog
❌ 只看 netstat -an,不看 ListenOverflows
❌ 把 SYN 队列和 accept 队列混为一谈


如果你能告诉我:

  • 是什么服务(Nginx / Java / Go / 自研)
  • 并发量 & 报错现象
  • ss -lntnetstat -s 输出

我可以给你更精确的调优方案

0