“改了 Linux 的 backlog 没生效”是一个非常常见的问题,通常不是你改的地方不对,而是被其他参数或机制限制了。下面按最常见原因系统说明。
在 Linux 网络里,backlog 至少涉及三层概念,容易混淆:
listen(sockfd, backlog);
你“改了 backlog”,通常指第 1 个,但真正生效的是第 2 个,且受限制。
net.core.somaxconn 限制实际 backlog = min(listen(backlog), net.core.somaxconn)
默认值通常是:
net.core.somaxconn = 128
listen(fd, 1024)sysctl -w net.core.somaxconn=4096
并写入:
/etc/sysctl.conf
net.core.somaxconn=4096
即使 accept queue 很大,syn 队列不够也会丢连接。
相关参数:
net.ipv4.tcp_max_syn_backlog
默认常见:
net.ipv4.tcp_max_syn_backlog = 1024
高并发场景建议:
sysctl -w net.ipv4.tcp_max_syn_backlog=8192
net.ipv4.tcp_backlog=...
(这个参数不存在)
net.core.somaxconnnet.ipv4.tcp_max_syn_backlog如果你用 systemd 启动服务(如 Nginx、自研服务):
[Service]
LimitNOFILE=...
但更重要的是:
systemd 不会自动继承 sysctl
而且某些程序 启动时只读一次 backlog。
cat /proc/<pid>/limits
很多服务器:
只在 listen() 时读一次 backlog
你之后改 sysctl:
sysctl -w net.core.somaxconn=4096
但不重启进程 = 无效
✅ 必须重启服务
这是最大误解。
backlog 只是:
已完成握手、但还没被 accept 的连接数
真正并发由:
决定。
ss -lnt
或
cat /proc/net/tcp
netstat -s | grep -i listen
关注:
times the listen queue of a socket overflowed
改 Linux backlog 无效,90% 是因为:
- 没改
net.core.somaxconn- 没重启服务
- 被 syn 队列限制
- 或误以为 backlog = 并发数
如果你愿意,可以告诉我:
我可以直接帮你定位到具体哪一步没生效。