发布于2026-06-30 阅读(0)
扫一扫,手机访问
先说一个容易被忽略但又至关重要的细节:TCP 三次握手中,服务端收到 SYN 之后、还没等到 ACK 的那段“悬空”状态,其实藏着不少性能瓶颈。很多人在调优服务器时,只知道改 net.core.somaxconn,却忽略了半连接队列本身——结果就是高并发下客户端频频超时,服务端却一脸无辜。今天就把这块彻底说清楚。

半连接不是“已建立的连接”,而是 TCP 三次握手中,服务端收到 SYN 包、发送 SYN+ACK 后、尚未收到客户端 ACK 的中间状态。这些未完成握手的连接被暂存在内核的 syn queue(也叫 SYN backlog),其长度由 net.ipv4.tcp_max_syn_backlog 控制。它和 net.core.somaxconn(全连接队列上限)常被混淆,但二者作用不同:前者管“握手中的请求”,后者管“已完成握手、等待 accept() 的连接”。
直接读内核参数:
cat /proc/sys/net/ipv4/tcp_max_syn_backlog
常见默认值是 128 或 256(取决于内核版本和内存大小)。这个值太小会导致高并发短连接场景下 SYN 包被丢弃,表现为客户端超时或重传,服务端却看不到新连接进 ss -s 或 netstat -s | grep -i "listen overflows" —— 后者出现 “listen overflows” 就是半连接队列溢出的明确信号。
修改 /etc/sysctl.conf,添加或调整这一行:
net.ipv4.tcp_max_syn_backlog = 65535
然后执行:
sudo sysctl -p
注意三点:
tcp_max_syn_backlog 值不能超过 net.core.somaxconn,否则实际生效值会被截断为后者;所以务必先确认并同步调大 net.core.somaxconnsysctl net.ipv4.tcp_max_syn_backlogbacklog 参数(如 listen(fd, backlog) 中的 backlog)必须 ≤ tcp_max_syn_backlog,否则内核会静默截断——很多 Go/Python 服务默认用 128,远低于调优后的系统值,得同步改代码或启动参数半连接队列溢出不只看单个参数。以下情况会让配置“看似生效实则无效”:
net.ipv4.tcp_syncookies:设为 1(默认开启)时,内核在队列满时会启用 cookie 机制伪造 SYN+ACK,掩盖溢出问题,但会增加延迟和 CPU 开销;若要真实压测队列容量,可临时关掉:echo 0 > /proc/sys/net/ipv4/tcp_syncookiesbacklog 值:比如 Nginx 默认 listen ... backlog=511,而系统设了 65535,但 511 仍远小于它;需在 nginx.conf 的 listen 指令里显式加 backlog=65535net.core.somaxconn 过低:它既是全连接队列上限,也间接约束半连接队列最大值;建议至少设为相同量级,例如都设成 65535真正有效的半连接调优,是 tcp_max_syn_backlog、somaxconn、应用层 backlog 三者对齐,且关闭 syncookie 干扰后实测 listen overflows 计数不再增长。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
4
5
6
7
8
9