Linux 中 backlog 满 一般指的是 TCP listen backlog 队列满了,导致新连接无法建立。下面从原理、常见原因、排查和解决方法几个层面说明。
在 Linux 网络编程中,服务端通常流程是:
socket()
bind()
listen(fd, backlog)
accept()
listen() 中的 backlog 表示:
已完成三次握手、但尚未被 accept() 取走的 TCP 连接队列长度上限
在 Linux 中,这个队列实际上分为两部分(内核实现细节):
| 队列 | 说明 |
|---|---|
| 半连接队列(SYN queue) | 收到 SYN,未完成三次握手 |
| 全连接队列(Accept queue) | 完成三次握手,等待 accept() |
backlog 满通常指“全连接队列(Accept queue)满了”
当 backlog 满时:
connect timeoutconnection refusedTCPBacklogDropListenOverflows(可通过 netstat -s 看到)listen(fd, 5); // 太小
即便是现代高并发服务,5 也明显不够。
✅ 推荐值:
listen(fd, 1024);
⚠️ 注意:
backlog 实际值会受内核参数限制
内核会取:
min(backlog, net.core.somaxconn)
如果:
cat /proc/sys/net/core/somaxconn
128
即使程序设了 1024,也只生效 128。
✅ 解决方法:
sysctl -w net.core.somaxconn=4096
或写入 /etc/sysctl.conf:
net.core.somaxconn=4096
如果半连接队列也满,会影响新连接建立。
查看:
cat /proc/sys/net/ipv4/tcp_max_syn_backlog
建议:
sysctl -w net.ipv4.tcp_max_syn_backlog=8192
即使 backlog 足够大:
accept() 不及时也会导致队列堆积。
✅ 优化方式:
epoll比如:
✅ 应对:
攻击者大量发送 SYN,不完成握手。
✅ 启用 SYN Cookie:
sysctl -w net.ipv4.tcp_syncookies=1
netstat -s | grep -i listen
示例:
1382 times the listen queue of a socket overflowed
✅ 说明 backlog 确实满了
ss -lnt
示例:
LISTEN 0 128 0.0.0.0:80
128 是当前 backlogRecv-Q 接近该值,说明队列快满netstat -s | grep TCPBacklogDrop
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_syncookies = 1
程序:
listen(fd, 1024);
Linux backlog 满 = 连接已就绪,但应用 accept 不及时或队列太小,导致新连接被丢弃
如果你愿意,可以告诉我:
ListenOverflows我可以帮你精准定位到具体哪一项配置或代码问题。