“Linux 的 backlog 很小”这个说法,通常指的是 TCP listen 的 backlog(全连接队列长度) 或者 半连接队列(SYN queue),而不是“Linux 本身小”。这是一个历史 + 内核设计 + 参数语义变化共同导致的问题。下面分层解释。
在 Linux 网络里,至少有两个 backlog:
listen(fd, backlog);
SYN_RECV 状态的连接你感觉“很小”,一般是指 listen(fd, backlog) 设置的值没生效,或者很快满了。
listen(backlog) 并不等于队列长度在老版本 Linux(< 2.4.25):
实际 backlog = listen(backlog)
在 2.4.25+ / 2.6+:
实际 backlog = min(backlog, /proc/sys/net/core/somaxconn)
而 somaxconn 默认值长期是:
128
✅ 所以你写:
listen(fd, 100000);
实际还是 128
所以 128 是“安全 + 够用”的默认值
/proc/sys/net/ipv4/tcp_max_syn_backlog
默认值通常:
而且:
SYN queue ≤ tcp_max_syn_backlog
如果 SYN 太多:
当 accept 队列满:
结果:
Linux 的观点是:
backlog 只是“短暂缓冲”,不是“海量堆积”
原因:
所以:
# 全连接队列上限
sysctl -w net.core.somaxconn=65535
# 半连接队列
sysctl -w net.ipv4.tcp_max_syn_backlog=65535
# SYN Cookie(防 SYN Flood)
sysctl -w net.ipv4.tcp_syncookies=1
写入 /etc/sysctl.conf 永久生效。
listen(fd, 65535);
⚠️ 但仍受 somaxconn 限制
backlog 不是用来扛压力的
而是:
突发连接时的“缓冲带”
正确架构:
Linux backlog 很小,不是能力问题,而是“默认保守 + 历史遗留 + 参数语义误导”
listen(backlog)≠ 实际队列长度
真正限制你的是somaxconn和tcp_max_syn_backlog
如果你愿意,我可以: