关于TCP overflowed、全连接、半连接队列

2020-05-02 11:59:35 浏览数 (1)

背景

最近遇到多台CVM中客户端访问服务器端超时的异常,当时查看了netstat -as信息,凭经验判断可能是tcp overflowed导致的。网卡队列满了,可能会造成子机网络包重传现象

netstat -as 信息截图netstat -as 信息截图

探究全连接、半连接

但是全连接和半连接是什么回事呢?我们一起探究探究

这个得从TCP三次握手说起,

TCP 三次握手过程TCP 三次握手过程

相信大家对三次握手都了然于胸,但是如果把这个过程放到linux环境下,结合linux内核的实现逻辑后是个什么形态呢?

TCP 三次握手过程详细版TCP 三次握手过程详细版

这里有两个队列:

  • 半连接队列:SYN queue ,长度由tcp_max_syn_backlognet.core.somaxconn和 业务tcp调用listen(fd, backlog)的backlog三者最小值决定
  • 全连接队列:ACCEPT queue , 长度由net.core.somaxconnlisten(fd, backlog)的backlog两者最小值决定

三次握手过程详情:

  1. Client端通过connect()系统调用,向Sever发起连接。发送SYN报文,进入SYN_SEND状态。
  2. Server收到SYN包,
    1. 如果全连接队列未满,将连接信息放到半连接队列中,进入SYN_RECV状态(也被称为半连接状态)。然后答复SYN ACK报文给Client
    2. 如果全连接队列满了,那么丢弃当前请求
  3. Client收到SYN ACK后,进行最后确认,向Server发送ACK报文,进入ESTABLISHED状态
  4. Server收到Client的ACK报文,
    1. 如果全连接队列未满,那么从半连接队列拿出相关信息放入到全连接队列中,进入ESTABLISHED状态
    2. 如果全连接队列满了并且tcp_abort_on_overflow是0的话,server过一段时间再次发送SYN ACK给Client(即重走握手的第二步)。如果Client超时等待设置较短,就会引发异常

监控方法

代码语言:javascript复制
netstat -as

如下图中所示信息:

全连接队列满了:xxx times the listen queue of a socket overflowed

半连接队列满了:xxx SYNs to LISTEN sockets dropped

可以通过监控数值是否增加,来判断是否存在异常

优化方式

调高

net.core.somaxconn

net.ipv4.tcp_max_syn_backlog

同时,提升 listen(fd, backlog) 的 backlog

0 人点赞