网络栈调优98 条

SYN_RECV 堆积诊断

半连接堆积常见于 SYN 队列满或来源伪造: 用状态计数与内核计数器交叉确认。

半连接堆积诊断

服务端收到 SYN 后、握手完成之前的连接处于半连接状态。这类连接堆积只有两种来源:突发流量超过了队列容量,或者来源地址是伪造的(典型的 SYN Flood)。要区分它们,需要把连接状态计数与内核同步 cookie 计数结合起来看;同时要与「已建连但应用不接受」造成的接受队列溢出分开判断,因为处置方向完全不同。

基本信息

适用平台Linux 服务端
观察命令连接状态列举工具与内核统计输出
关键计数同步 cookie 发送数、半连接队列丢弃、接受队列溢出
相关参数net.ipv4.tcp_max_syn_backlog、net.ipv4.tcp_synack_retries、net.ipv4.tcp_syncookies
权限要求查看无需特权,修改参数需要 root

典型使用场景

  • 服务在流量高峰出现连接超时,怀疑半连接队列不足。
  • 遭受扫描或伪造源攻击时确认现象特征。
  • 区分两类队列溢出,避免改错参数。
  • 限速或清洗设备上线后确认堆积是否缓解。
  • 核对握手重试次数对堆积停留时长的影响。

观察与交叉确认

观察与交叉确认
ss -tan state syn-recv | wc -l                       # 当前半连接规模
ss -lnt | head                                       # 监听行的队列列,判断接受侧是否也在涨
netstat -s | grep -iE 'SYNs to LISTEN|SYN cookies|listen queue'   # 握手与队列相关计数
nstat -az TcpExtListenOverflows TcpExtListenDrops    # 接受队列溢出与总丢弃
sysctl net.ipv4.tcp_max_syn_backlog net.ipv4.tcp_synack_retries net.ipv4.tcp_syncookies

计数与含义

计数变化含义处置方向
同步 cookie 发送数上涨半连接队列容量成为限制评估队列容量与流量特征
接受队列溢出计数上涨应用接受连接太慢转向应用与工作线程排查
半连接丢弃计数上涨且来源分散可能存在伪造源结合来源分布与防护策略
状态数短暂冲高后回落正常突发观察即可,不必改参数
握手重试次数决定了半连接在内核里停留的时间:次数越多,单位时间内占用队列的连接就越多,容量紧张时这个参数的影响不比队列长度小。
不要为了「清理堆积」关闭同步 cookie 防护:它在队列满时仍能完成合法握手,是抵御伪造源的重要手段,关闭会把容量问题变成可用性问题。

易错点

  • 把半连接与接受队列两类溢出混为一谈:一个是握手阶段,一个是应用接受阶段,改错参数不会有任何改善。
  • 未核实来源真实性就扩大队列:面对伪造源时扩大队列只会消耗更多内核资源。
  • 关掉同步 cookie 以「减少异常」:同时削弱了抵御伪造源的能力,风险明显升高。
  • 只看瞬时计数不看趋势:突发流量造成的短期冲高与持续堆积含义不同,需要结合时间窗口判断。
  • 忽略握手重试次数:它决定堆积的持续时间,容量调整时容易被漏掉。

数据来源与参考

  • man ss
  • man netstat
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌