在 Linux 网络编程(尤其是 TCP 服务端)中,backlog 是一个非常重要但经常被误解的参数。它直接影响连接建立的性能、稳定性和可靠性。下面从“是什么、为什么重要、不设好会怎样”三个层面说明。
在 TCP 服务端,通常流程是:
socket()
bind()
listen(sockfd, backlog)
accept()
listen() 的 backlog 参数,用来限制内核中“已完成连接”或“正在握手”的队列长度(不同内核版本含义略有差异)。
简化理解:
客户端 -> [半连接队列] -> [全连接队列] -> accept()
↑ backlog 相关
accept() 取走backlog 主要影响全连接队列长度(在老内核中也影响半连接)。
如果 全连接队列满了:
➡️ 高并发服务(Web、RPC、网关)中,这是隐形故障源头。
比如:
如果 backlog 太小:
如果 backlog 合理:
acceptaccept() 是用户态行为,可能慢(业务逻辑、锁、GC)。
backlog 相当于:
内核帮你“接住”连接,等你来处理
太小 → 内核接不住
太大 → 内存+CPU 成本上升(但不致命)
很多诡异问题:
telnet 能通最后发现:
backlog = 5 或 10(默认值太小)
128 ~ 5121024 ~ 4096net.core.somaxconn
实际生效的是:
min(backlog, net.core.somaxconn)
查看:
cat /proc/sys/net/core/somaxconn
修改:
sysctl -w net.core.somaxconn=4096
backlog 决定了“内核能帮你接住多少连接”
它重要,是因为:
如果你愿意,我也可以: