在 Linux 网络编程中,backlog 溢出通常指的是 TCP 监听队列(accept queue)溢出,导致新连接被丢弃或重传。下面从原理到常见原因系统说明。
以 listen(fd, backlog) 为例:
listen(sockfd, backlog);
在 Linux 中,backlog 实际上控制的是“已完成连接队列(accept queue)”的长度上限(不同内核版本略有差异):
accept()当 accept queue 满了,就是常说的 backlog 溢出。
netstat 中 Recv-Q 很大ss -lnt 中 Recv-Q 接近 Send-Qdmesg 或 /proc/net/netstat 中:ListenOverflows / ListenDrops 增加
accept() 太慢这是最常见原因。
accept() 调用频率低结果:
已完成连接堆在 accept queue
backlog 满了 → 新连接被丢弃
✅ 解决:
acceptlisten(fd, 5); // 太小
在高并发场景下远远不够。
✅ 建议:
listen(fd, 1024);
⚠️ 注意:
min(backlog, net.core.somaxconn)somaxconn=128(很多发行版)查看:
cat /proc/sys/net/core/somaxconn
修改:
sysctl -w net.core.somaxconn=4096
短时间大量连接:
即使 accept() 正常,也可能瞬间打满。
✅ 缓解:
虽然你说的是 backlog,但常常一起出现:
net.ipv4.tcp_max_syn_backlog 太小查看:
cat /proc/sys/net/ipv4/tcp_max_syn_backlog
现象:
accept() 不执行somaxconn 未生效ss -lnt
示例:
State Recv-Q Send-Q Local Address:Port
LISTEN 1024 1024 :::8080
Recv-Q == Send-Q → 队列满
netstat -s | grep -i listen
或:
nstat | grep -i listen
关注:
ListenOverflows
ListenDrops
✅ 应用层
accept()✅ 系统层
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
✅ 代码层
listen(fd, 1024);
Linux backlog 溢出,本质不是 backlog 小,而是“连接生产速度 > 消费速度”。
如果你愿意,可以贴出:
ss -lntlisten() 代码我可以帮你具体定位是哪一环的问题。