温馨提示×

linux backlog与tcp关系

小樊
45
2026-09-17 13:52:53
栏目: 智能运维

在 Linux 网络编程和内核网络栈中,backlogTCP 有非常紧密的关系,主要体现在 TCP 连接建立过程(三次握手)监听套接字(listen socket) 上。

下面分层次说明。


一、backlog 是什么

backloglisten() 系统调用中的一个参数:

int listen(int sockfd, int backlog);

它的含义是:
内核为该监听套接字维护的“半连接 + 全连接队列”长度上限(历史上含义有变化)


二、TCP 三次握手与队列

TCP 建立连接时,内核会维护两个队列:

1. 半连接队列(SYN Queue)

  • 收到客户端 SYN
  • 发送 SYN+ACK
  • 但还没收到 ACK

此时连接处于 SYN_RCVD 状态。

2. 全连接队列(Accept Queue)

  • 三次握手完成
  • 连接进入 ESTABLISHED
  • 等待应用程序调用 accept()
客户端 SYN
   ↓
[半连接队列]
   ↓
客户端 ACK
   ↓
[全连接队列]
   ↓
accept()

三、backlog 控制的是什么

早期 BSD

  • backlog = 全连接队列长度

Linux(历史变化)

  • 老版本:backlog 包含半连接 + 全连接
  • 新版本(2.2+):
    • backlog 主要限制 全连接队列(accept queue)
    • 半连接队列由 /proc/sys/net/ipv4/tcp_max_syn_backlog 控制

实际长度还受限制

在 Linux 中:

实际全连接队列长度 = min(backlog, /proc/sys/net/core/somaxconn)
  • somaxconn 默认通常是 128
  • 即使 listen(fd, 1000),也可能只有 128

四、backlog 不够会发生什么(TCP 层表现)

1. 全连接队列满

  • 已完成三次握手的连接无法入队
  • 客户端可能:
    • 连接超时
    • 收到 RST
  • 服务端 ESTABLISHED 连接数不增加

2. 半连接队列满

  • 新 SYN 被丢弃
  • 客户端重传 SYN
  • 表现为连接建立慢、超时

五、为什么 backlog 很重要(TCP 服务)

常见场景:

场景 问题
高并发短连接 全连接队列易满
突发流量 SYN 风暴
accept 慢 队列堆积

典型表现:

  • ss -lntRecv-Q 接近 Send-Q
  • netstat 大量 SYN_RECV
  • 客户端连接失败但服务端看似正常

六、相关内核参数(Linux)

# 全连接队列上限
/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 讲实际调优。

0