温馨提示×

什么是TCP backlog

小樊
74
2026-07-18 07:44:29
栏目: 编程语言

TCP backlog 是 Linux(及类 Unix 系统)中,用于 TCP 连接建立过程中,控制“已完成握手”和“未完成握手”连接队列长度的一个参数。它直接影响服务端能同时接受多少新连接。

下面从原理到实践系统说明。


一、TCP 建连回顾(三次握手)

  1. 客户端发送 SYN
  2. 服务端收到 SYN,回复 SYN+ACK
    • 此时连接进入 半连接状态
  3. 客户端发送 ACK
    • 连接进入 全连接状态

在这两个阶段,内核分别为连接维护两个队列:

队列 名称 保存的连接
半连接队列 SYN queue 收到 SYN,但未完成三次握手
全连接队列 Accept queue 三次握手完成,但尚未被 accept()

二、什么是 TCP backlog

1️⃣ backlog 的作用

backlog应用层在调用 listen() 时,告诉内核:
“我最多能处理多少个已经完成三次握手的连接”

int listen(int sockfd, int backlog);

✅ backlog 主要影响的是“全连接队列(Accept queue)”的大小


三、全连接队列大小怎么算?

在 Linux 中,真实的全连接队列大小 不是 backlog 本身,而是:

min(backlog, net.core.somaxconn)

举例

listen(fd, 128);

如果:

cat /proc/sys/net/core/somaxconn
# 输出 4096

那么实际队列大小 = 128

如果:

somaxconn = 64

那么实际队列大小 = 64

backlog 是上限,somaxconn 是最终限制


四、半连接队列(SYN queue)

半连接队列大小由以下参数控制(与 backlog 间接相关):

net.ipv4.tcp_max_syn_backlog

例如:

cat /proc/sys/net/ipv4/tcp_max_syn_backlog
# 常见 256 / 512 / 2048

SYN flood 攻击时,这个队列非常关键。


五、队列满了会发生什么?

1️⃣ 全连接队列满

  • 新完成的握手连接 无法进入 accept 队列
  • 客户端可能:
    • 超时
    • 重传
    • 连接失败

⚠️ 服务看起来“卡住”或“拒绝连接”


2️⃣ 半连接队列满

  • 新 SYN 包可能被:
    • 丢弃
    • 直接忽略

六、backlog 设多大合适?

常见建议

场景 backlog
普通 Web 服务 128~512
高并发服务 1024~4096
网关 / 代理 4096 或更高

⚠️ 单纯加大 backlog 没用,还要同步调整内核参数


七、关键内核参数速查

# 全连接队列上限
net.core.somaxconn

# 半连接队列上限
net.ipv4.tcp_max_syn_backlog

# SYN cookies(防 SYN flood)
net.ipv4.tcp_syncookies

推荐配置(高并发)

net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_syncookies = 1

八、一个完整的理解公式

实际全连接队列大小 = min(listen backlog, net.core.somaxconn)

九、一句话总结

TCP backlog 是应用层向内核声明的“已完成三次握手的连接最大等待数量”,
它主要受 listen(backlog)net.core.somaxconn 共同限制。

如果你愿意,我可以:

  • 抓包 + 队列状态 帮你理解
  • 结合 Nginx / Redis / Java / Go 的实际例子说明
  • 帮你排查 “connection refused / timeout” 是否和 backlog 有关

只要告诉我你的使用场景即可。

0