你知道TCP的半连接与全连接队列吗?

TCP的半连接与全连接队列

  • TCP连接队列
    • 半连接队列
    • 全连接队列
    • TCP全连接队列策略
    • 设置TCP全连接队列
    • TCP半队列溢出
      • 最大半队列连接数
    • 服务端处于SYN_RECV状态的最大个数
    • syncookies

TCP连接队列

半连接队列

服务端收到客户端发起的 SYN 请求后,内核会把该连接存储到半连接队列(SYN队列),并向客户端响应 SYN+ACK。

全连接队列

服务端收到第三次握手的ACK后,内核会把连接从半连接队列移除,然后创建新的完全的连接,并将其添加到accept队列,等待进程调用accept 函数时把连接取出来。
你知道TCP的半连接与全连接队列吗?_第1张图片

TCP全连接队列策略

tcp_abort_on_overflow 共有两个值分别是0和1,其分别表示

  • 0:如果全连接队列满了,那么server扔掉client发过来的ack
  • 1:如果全连接队列满了,server发送⼀个reset包给client,表示废掉这个握手过程和这个连接

通常情况下,应当把tcp_abort_on_overflow设置为0,因为这样更有利于应对突发当TCP全连接队列满导致服务器丢掉了ACK,与此同时,客户端的连接状态却是ESTABLISHED,进程就在建立好的连接上发送请求。只要服务器没有为请求回复ACK,请求就会被多次重发。如果服务器上的进程只是短暂的繁忙造成accept队列满,那么当TCP全连接队列有空位时,再次接收到的请求报文由于含有 ACK, 仍然会触发服务器端成功建立连接。所以tcp_abort_on_overflow设为0可以提高连接建立的成功率,只有你非常肯定 TCP全连接队列会长期溢出时,才能设置为1以尽快通知客户端。

设置TCP全连接队列

TCP全连接队列的最大值取决于somaxconn和backlog之间的最小值,也就是 min(somaxconn, backlog)

  • somaxconn 是 Linux 内核的参数,默认值是 128,可以通过 /proc/sys/net/core/somaxconn来设置其值
  • backlog是listen(int sockfd, int backlog)函数中的backlog大小,Nginx默认值是511,可以通过修改配置文件设置其长度

如果持续不断地有连接因为 TCP 全连接队列溢出被丢弃,就应该调⼤ backlog 以及 somaxconn 参数。

TCP半队列溢出

  • 如果半连接队列满了,并且没有开启 tcp_syncookies,则会丢弃
  • 若全连接队列满了,且没有重传SYN+ACK包的连接请求多于1个,则会丢弃
  • 如果没有开启tcp_syncookies,并且max_syn_backlog减去当前半连接队列长度小于(max_syn_backlog >> 2),则会丢弃

最大半队列连接数

  • 当 max_syn_backlog > min(somaxconn, backlog) 时, 半连接队列最大值 max_qlen_log = min(somaxconn, backlog) * 2
  • 当 max_syn_backlog < min(somaxconn, backlog) 时, 半连接队列最大值 max_qlen_log = max_syn_backlog * 2

服务端处于SYN_RECV状态的最大个数

  • 如果当前半连接队列没超过理论半连接队列最大值,但是超过 max_syn_backlog - (max_syn_backlog >> 2),那么处于 SYN_RECV 状态的最大个数就是max_syn_backlog - (max_syn_backlog >> 2)
  • 如果当前半连接队列超过理论半连接队列最大值,那么处于SYN_RECV状态的最大个数就是理论半连接队列最大值

syncookies

开启 syncookies 功能就可以在不使用SYN半连接队列的情况下成功建立连接。syncookies 是这么做的:服务器根据当前状态计算出⼀个值,放在己方发出的SYN+ACK报文中发出,当客户端返回ACK报文时,取出该值验证,如果合法,就认为连接建立成功。

你知道TCP的半连接与全连接队列吗?_第2张图片
syncookies 参数主要有以下三个值

  • 0 值,表示关闭该功能
  • 1 值,表示仅当 SYN 半连接队列放不下时,再启用它
  • 2 值,表示无条件开启功能

你可能感兴趣的:(图解网络读书笔记,TCP半连接队列,TCP全连接队列)