温馨提示×

linux backlog和连接数关系

小樊
37
2026-09-14 13:07:27
栏目: 智能运维

在 Linux 网络(尤其是 TCP 服务端编程)中,backlog连接数是两个密切相关但含义不同的概念。下面从原理到实际关系给你讲清楚。


一、基本概念

1. 连接数(Connection Number)

指当前系统中存在的 TCP 连接数量,通常分为:

  • 已建立连接(ESTABLISHED)
  • 正在握手但未完成(SYN_RCVD)
  • 已连接但还未被 accept(在队列中)

2. backlog 是什么

backloglisten(sockfd, backlog) 中的参数,表示内核为该 socket 维护的“等待被 accept 的连接队列”长度上限

但要注意:

backlog 不是“最大连接数”


二、Linux 中 backlog 的真实含义(重点)

TCP 连接建立分两步队列(Linux 内核实现):

1️⃣ 半连接队列(SYN Queue)

  • 存放 收到 SYN,但未完成三次握手 的连接
  • 长度由:
    /proc/sys/net/ipv4/tcp_max_syn_backlog
    
    控制

2️⃣ 全连接队列(Accept Queue)

  • 存放 三次握手完成,但还未被应用 accept
  • 长度由:
    min(backlog, /proc/sys/net/core/somaxconn)
    
    决定

backlog 实际影响的是“全连接队列”长度


三、backlog 和连接数的关系

关系总结一句话:

backlog 限制的是“已建立但未被 accept 的连接数”,而不是总连接数

示意图

客户端
  |
  | SYN
  v
[半连接队列]
  |
  | ACK
  v
[全连接队列]  <-- backlog 限制这里
  |
  | accept()
  v
应用程序

四、举例说明

假设:

  • somaxconn = 128
  • listen(sock, 50)

那么:

  • 全连接队列最大 = 50
  • 可同时有:
    • 50 个已建立但未被 accept 的连接
    • 加上正在被应用处理的连接(accept 之后)

如果:

  • 应用 accept() 很慢
  • 队列满了

那么:

  • 新完成的握手会被 丢弃或重传
  • 客户端表现为连接超时

五、连接数上限由什么决定?

真正的“最大连接数”受以下影响:

项目 说明
文件描述符限制 ulimit -n
内存 每个连接占用内核内存
somaxconn accept 队列上限
tcp_max_syn_backlog 半连接上限
应用处理能力 accept + 业务处理速度

六、常见误区

❌ backlog = 最大连接数
✅ backlog = 已建立但未被 accept 的队列长度

❌ 调大 backlog 就能支持更多并发
✅ 还要应用能及时 accept

❌ SYN 攻击只和 backlog 有关
✅ 还和 tcp_max_syn_backlogtcp_syncookies 有关


七、调优建议

# 提高 accept 队列
echo 1024 > /proc/sys/net/core/somaxconn

# 提高半连接队列
echo 8192 > /proc/sys/net/ipv4/tcp_max_syn_backlog

# 防止 SYN 洪水
echo 1 > /proc/sys/net/ipv4/tcp_syncookies

代码中:

listen(sock, 1024);

如果你愿意,我也可以:

  • 画一张 队列+状态图
  • 结合 Nginx / Redis / 自写 server
  • 分析你遇到的 连接满 / 超时问题

直接说场景就行。

0