在 Linux 网络编程中,backlog 导致连接“丢失”(更准确说是被丢弃或无法建立)是一个经典问题,原因涉及内核参数、TCP 协议行为和应用程序处理速度。下面系统说明。
以 listen(sockfd, backlog) 为例:
listen(sockfd, backlog);
backlog 不是“总连接数上限”,而是:
已完成三次握手、但还没被
accept()取走的连接队列长度上限
Linux 中实际涉及两个队列:
accept()backlog 主要影响 accept 队列
当:
accept() 太慢或没调用→ accept 队列满
→ 新完成的连接被丢弃
表现:
Linux 实际队列长度:
min(backlog, /proc/sys/net/core/somaxconn)
默认:
net.core.somaxconn = 128
即使你写:
listen(sock, 1024);
实际可能只有 128
✅ 解决:
sysctl -w net.core.somaxconn=1024
受以下参数影响:
net.ipv4.tcp_max_syn_backlog
如果:
→ SYN 被丢弃
→ 客户端重传,最终失败
net.ipv4.tcp_syncookies = 1
作用:防止 SYN flood
代价:
✅ 高并发场景常见现象
例如:
结果:
即使连接“在队列里”:
看起来像“连接丢失”
| 现象 | 可能原因 |
|---|---|
| 客户端超时 | accept 队列满 |
| 客户端 RST | 服务端丢弃连接 |
| 大量 SYN 重传 | SYN 队列满 |
| 连接数上不去 | somaxconn 太小 |
| 偶发失败 | accept 不及时 |
ss -lnt
关注:
Recv-QSend-Qnetstat -s | grep -i listen
sysctl net.core.somaxconn
sysctl net.ipv4.tcp_max_syn_backlog
listen(fd, 1024);
如果你愿意,我可以:
给你更针对性的建议。