在 Linux 网络编程和内核中,backlog 被“重置”或不如预期生效,通常不是真的“随机清零”,而是由以下几类原因导致的。下面按常见程度说明。
net.core.somaxconn 限制(最常见)listen(sockfd, backlog);
实际生效的队列长度是:
min(backlog, net.core.somaxconn)
查看:
cat /proc/sys/net/core/somaxconn
# 常见默认是 128
如果你设置:
listen(sockfd, 1024);
但 somaxconn=128,那么 backlog 实际只有 128。
✅ 解决:
sysctl -w net.core.somaxconn=65535
并在 /etc/sysctl.conf 中持久化。
Linux 中其实有 两个队列:
| 队列 | 说明 |
|---|---|
| SYN 队列 | 半连接(收到 SYN,未完成三次握手) |
| accept 队列 | 全连接(完成握手,等待 accept()) |
net.ipv4.tcp_max_syn_backlog 影响cat /proc/sys/net/ipv4/tcp_max_syn_backlog
如果 SYN 过多,SYN 队列满:
启用 TCP Fast Open 后:
查看:
cat /proc/sys/net/ipv4/tcp_fastopen
listen() 在代码中写死systemd 限制了资源检查:
systemctl show your.service | grep -i backlog
如果你的程序:
accept() 非常快那么:
这是正常行为,不是重置。
在 Docker / K8s 中:
somaxconn 可能沿用宿主机或被限制检查:
kubectl exec pod -- cat /proc/sys/net/core/somaxconn
不同内核版本:
所以老资料会误导你。
# 1. 实际 backlog 上限
cat /proc/sys/net/core/somaxconn
# 2. SYN 队列上限
cat /proc/sys/net/ipv4/tcp_max_syn_backlog
# 3. 当前监听端口队列
ss -lnt
# Send-Q 就是实际 backlog
Linux 的 backlog“被重置”,99% 是因为被
somaxconn或 SYN 队列上限截断了,而不是真的清零。
如果你愿意,可以告诉我:
我可以帮你精确定位。