解决高并发tcp代理syn队列溢出需四层协同:调大tcp_max_syn_backlog、somaxconn及应用层backlog三者匹配;启用tcp_syncookies=1并降低tcp_synack_retries;结合iptables限速、关闭非必要端口、前置反代复用连接及优化健康检查。

解决高并发TCP代理下SYN队列溢出,核心是让半连接队列“不积压、不丢包、有兜底”。不能只靠调大一个参数,必须从内核队列容量、连接生命周期、协议层防护、网络层过滤四层协同入手。
确认是否真发生SYN队列溢出
别凭现象猜,用指标验证:
- 执行 netstat -s | grep -i "listen overflows\|SYNs to LISTEN",数值持续上涨即确认溢出
- 查当前半连接数:ss -n state syn-recv | wc -l,再对比 cat /proc/sys/net/ipv4/tcp_max_syn_backlog,若接近或超限就是瓶颈
- 看内核日志:dmesg | grep -i "possible SYN flooding",出现该提示说明已触发保护但未启用syncookies
同步调大三个关键队列上限
半连接队列(SYN Queue)、全连接队列(Accept Queue)、应用层 backlog 必须匹配,否则调大一个等于白做:
- tcp_max_syn_backlog:控制每个监听套接字的半连接队列长度。代理类服务建议设为 8192~65535(如突发峰值每秒3000 SYN,可设为6000)
- somaxconn:全连接队列上限,必须 ≥ tcp_max_syn_backlog,推荐统一设为 65535
- 应用层 backlog:Nginx 配置加 listen 80 backlog=65535;Envoy 启动加 --max-concurrent-connections=65535;自研代理用 socket.listen() 时显式传入大值(如 Python 的 listen(65535))
启用SYN Cookies并压缩重试时间
这是最可靠的兜底机制,队列满时自动切换为无状态响应,不占内存:
- 开启:sysctl -w net.ipv4.tcp_syncookies=1(永久写入 /etc/sysctl.conf)
- 验证生效:sysctl net.ipv4.tcp_syncookies 返回 1,且 netstat -s | grep -i syncookies 中 “Syncookies sent” 计数增长
- 缩短 tcp_synack_retries:从默认 5 降为 2 或 3,使无效连接平均驻留时间从 31 秒压至 1–3 秒,大幅释放队列空间
前置过滤与架构减负
内核参数是底线,网络层过滤和代理设计才是治本:
- 对单 IP 限速:iptables -A INPUT -p tcp --dport [代理端口] --syn -m limit --limit 5/sec --limit-burst 15 -j ACCEPT,超限直接丢弃
- 关闭非必要端口监听,尤其管理端口、调试端口,减少攻击面
- 在代理前端加一层轻量反向代理(如 Nginx),启用 keepalive 复用连接,把大量短连接转化为长连接,显著降低后端 SYN 到达速率
- 检查健康探活频率——避免客户端或LB每秒多次 TCP connect,应改用 HTTP /health 等更轻量方式











