在 Linux 中,backlog 通常出现在两个层面:
下面从原理 → 查看 → 优化三个层面说明。
listen(fd, backlog);
backlog 表示 已完成三次握手、等待 accept 的 socket 数量上限(全连接队列)。
⚠️ 实际队列长度 ≠ backlog
实际值 =min(backlog, net.core.somaxconn)
| 队列 | 说明 | 对应参数 |
|---|---|---|
| 半连接队列 | SYN 已收到,未完成握手 | net.ipv4.tcp_max_syn_backlog |
| 全连接队列 | 已完成握手,等待 accept | net.core.somaxconn + listen(backlog) |
sysctl net.core.somaxconn
sysctl net.ipv4.tcp_max_syn_backlog
ss -lnt
示例:
State Recv-Q Send-Q Local Address:Port
LISTEN 0 128 :::80
Send-Q = 当前 backlog 上限Recv-Q 接近 Send-Q,说明队列快满了netstat -s | grep -i listen
或
nstat | grep -i listen
关注:
ListenOverflowsListenDrops# 临时
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_max_syn_backlog=65535
# 永久
vim /etc/sysctl.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
sysctl -p
很多程序默认 backlog 很小(如 128、511)
listen 80 backlog=65535;
tcp-backlog 65535
serverSocket.bind(new InetSocketAddress(port), 65535);
net.ListenConfig{}.Listen(ctx, "tcp", addr)
// 依赖系统 somaxconn
backlog 再大,如果:
都会堆满队列。
优化方向:
SO_REUSEPORTnet.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
❌ 只改 listen(backlog) 不生效
✅ 必须同时调 somaxconn
❌ backlog 越大越好
✅ 队列只是缓冲,处理能力才是根本
❌ 忽略 accept 性能
✅ 队列满了仍然会丢连接
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_syncookies = 1
应用 backlog ≥ 1024(建议 65535)
如果你能告诉我:
ListenOverflows 是否增长我可以给你更精确的优化方案。