温馨提示×

怎样理解linux backlog

小樊
44
2026-09-08 10:22:26
栏目: 智能运维

在 Linux 网络编程里,backlog 是一个经常让人困惑的概念,尤其在使用 listen() 函数时。下面从定义、历史演变、内核实现、实际影响几个层面帮你理清。


一、backlog 是什么?

在 TCP 服务器中,典型流程是:

socket();
bind();
listen(sockfd, backlog);
accept();

listen() 的第二个参数 backlog,字面意思是“等待被处理的连接队列长度”,但不同 Linux 版本含义并不一样。


二、历史中的 backlog 含义(容易误解)

早期 BSD 定义

backlog = 已完成连接(ESTABLISHED)队列的最大长度

也就是说:

  • 三次握手完成
  • 但还没被 accept()
  • 这些连接放在队列里

Linux 2.2 之前

  • 只有一个队列
  • backlog 同时限制:
    • 半连接(SYN_RECV)
    • 全连接(ESTABLISHED)

三、Linux 现代实现(2.2+,重点)

Linux 将连接队列分成 两个队列:

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

  • 状态:SYN_RECV
  • 收到 SYN,但三次握手未完成
  • 长度由内核参数控制:
/proc/sys/net/ipv4/tcp_max_syn_backlog

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

  • 状态:ESTABLISHED
  • 三次握手完成,等待 accept()
  • backlog 限制的是这个队列

四、backlog 实际是怎么用的?

Linux 中:

max_qlen = min(backlog, somaxconn)
  • somaxconn 默认是 128
  • 你写的 listen(fd, 1000),实际可能是 128

查看:

cat /proc/sys/net/core/somaxconn

修改:

sysctl -w net.core.somaxconn=1024

五、队列满了会怎样?

全连接队列满

  • 新完成的握手 不会被放入队列
  • 客户端可能:
    • 连接成功但 server 不 accept
    • 或收到 RST

半连接队列满

  • 忽略 SYN(或丢包)
  • 客户端表现为超时重传

六、一个通俗比喻

把 server 想成餐厅:

  • 半连接队列:门口等位区(还没入座)
  • 全连接队列:已经入座、等服务员点餐
  • backlog:店里能坐多少桌
  • accept():服务员来点餐

如果桌子坐满了,新客人只能站着或走人。


七、实际开发建议

常见错误

listen(fd, 5);  // 太小

推荐做法

listen(fd, 1024);

并配合:

net.core.somaxconn = 1024

高并发服务

  • Web / RPC / 网关
  • 通常设为 1024~4096

八、和 backlog 相关的参数汇总

参数 作用
net.core.somaxconn 全连接队列上限
net.ipv4.tcp_max_syn_backlog 半连接队列上限
net.ipv4.tcp_syncookies 防 SYN 泛洪
backlog in listen() 用户态建议值

九、一句话总结

Linux 中的 backlog,本质是“已完成连接、等待 accept 的队列长度上限”,但真实长度受 somaxconn 限制。

如果你愿意,我也可以:

  • 画一张 TCP 队列图
  • 结合 Nginx / Redis / Java Netty 讲
  • 用 ss -lnt 实际看队列状态

0 踩