在 Linux 网络编程和内核网络栈中,backlog 和 TCP 有非常紧密的关系,主要体现在 TCP 连接建立过程(三次握手) 和 监听套接字(listen socket) 上。
下面分层次说明。
backlog 是 listen() 系统调用中的一个参数:
int listen(int sockfd, int backlog);
它的含义是:
内核为该监听套接字维护的“半连接 + 全连接队列”长度上限(历史上含义有变化)。
TCP 建立连接时,内核会维护两个队列:
此时连接处于 SYN_RCVD 状态。
ESTABLISHEDaccept()客户端 SYN
↓
[半连接队列]
↓
客户端 ACK
↓
[全连接队列]
↓
accept()
backlog = 全连接队列长度backlog 主要限制 全连接队列(accept queue)/proc/sys/net/ipv4/tcp_max_syn_backlog 控制在 Linux 中:
实际全连接队列长度 = min(backlog, /proc/sys/net/core/somaxconn)
somaxconn 默认通常是 128listen(fd, 1000),也可能只有 128ESTABLISHED 连接数不增加常见场景:
| 场景 | 问题 |
|---|---|
| 高并发短连接 | 全连接队列易满 |
| 突发流量 | SYN 风暴 |
| accept 慢 | 队列堆积 |
典型表现:
ss -lnt 中 Recv-Q 接近 Send-Qnetstat 大量 SYN_RECV# 全连接队列上限
/proc/sys/net/core/somaxconn
# 半连接队列上限
/proc/sys/net/ipv4/tcp_max_syn_backlog
# SYN Cookie(队列满时启用)
/proc/sys/net/ipv4/tcp_syncookies
Linux 中的 backlog 本质是 TCP 监听套接字在“连接建立阶段”用来缓存已完成或正在进行三次握手连接的队列长度限制,它直接影响 TCP 连接能否被高效接受。
如果你愿意,我也可以画一张 TCP 状态 + 队列对照图,或者结合 Nginx / Redis / 自写 server 讲实际调优。