TCP 流分析82 条

SYN 队列与半连接

握手未完成时连接保存在 SYN 队列:队列满会丢弃新 SYN 或启用 SYN Cookie 兜底,抓包表现为部分 SYN 无响应或响应延迟。

SYN 队列是什么

服务端来不及完成三次握手时,尚未建立的连接会先进入 SYN 队列(半连接队列),队列长度受 net.ipv4.tcp_max_syn_backlog 与监听套接字的 backlog 参数共同限制。队列满之后新到的 SYN 会被直接丢弃,抓包表现为部分 SYN 完全没有响应,客户端只能按重传超时重试;内核启用 SYN Cookie 后会改为不保存状态的校验方式兜底,握手仍能完成而资源占用更低。判断这个问题要同时看 SYN 到达速率、握手完成率和当前队列占用,只看其中一项都会误判。

基本信息

相关参数tcp_max_syn_backlog、tcp_syncookies、somaxconn
查看方式ss -s 看汇总,sysctl 看参数当前值
抓包特征部分 SYN 无响应,或响应延迟明显偏大
客户端表现建连超时,重试后偶发成功
常见诱因突发建连量、SYN 洪泛、客户端不回 ACK

典型使用场景

  • 建连成功率下降:客户端报告偶发连接超时,但服务端应用日志里没有任何记录
  • 压测分析:并发建连场景下观察半连接数量与完成率之间的关系
  • 容量评估:确认队列长度与业务峰值建连速率是否匹配
  • 攻击识别:SYN 洪泛会让半连接队列长期处于占满状态
  • 容器环境排查:容器网络同样受宿主内核这组参数约束,需要联合观察

查看与判断

查看与判断
ss -s | grep -i syn                      # 汇总中的半连接与相关计数
ss -lnt                                   # 查看监听队列的当前值
sysctl net.ipv4.tcp_max_syn_backlog net.ipv4.tcp_syncookies
# 抓包侧对比 SYN 数量与最终完成握手的比例

观察点与含义

观察点正常表现异常表现
SYN 与 SYN-ACK 数量基本一一对应SYN 多出很多说明队列丢弃或路径丢包
半连接计数随负载小幅波动长期贴顶说明容量不足或遭受洪泛
握手完成时延与 RTT 同量级明显偏大说明排队或重试
客户端重试次数偶发集中出现说明服务端丢弃了 SYN
启用 SYN Cookie 时服务端不保留半连接状态,抓包形态与普通握手没有区别,但抗洪泛能力更强,这是被广泛推荐的兜底配置。
队列长度并非越大越好:过大的队列会把瞬时压力转成更长的等待时间,掩盖客户端连接复用不足、并发设计不合理等根本原因。

易错点

  • 半连接堆积多数由客户端只发 SYN 不回 ACK 或路径丢包造成,直接调大队列只是掩盖现象,应先定位发起侧
  • 只看服务端应用日志会漏掉这类故障:队列满时 SYN 在建立连接之前就被丢弃,业务日志里不留任何痕迹
  • 容器与宿主共享同一组内核参数,只在容器内排查会看不到全局队列占用情况
  • 队列调得过大在被攻击时反而要消耗更多内存保存半连接状态,需要与 SYN Cookie 一并评估取舍

数据来源与参考

  • Linux ip-sysctl 文档
  • RFC 4987
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌