zoukankan      html  css  js  c++  java
  • net.ipv4.tcp_tw_reuse & net.ipv4.tcp_tw_recycle

    参数设置

    默认情况下tcp_tw.recycle & tc_tw_reuse是关闭的,即值为1;tcp_timestamps默认情况下开启的

    tcp_recycle在4.10内核已不在使用,4.12版本的内核相关代码正式删除;tcp_tw_reuse则继续保留

    1. net.ipv4.tcp_tw_recycle = 1

    2. net.ipv4.tcp_tw_reuse = 1

    3. net.ipv4.tcp_timestamps = 1

    查看方法

    netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

    ss -ant | awk 'NR>1 {++s[$1]} END {for(k in s) print k,s[k]}'

    参数区别

    • tcp_tw_reuse

      官方引文

      Enable reuse of TIME-WAIT sockets for new connections when it is safe from protocol viewpoint.

      当在协议的角度安全时,开启复用TIME_WAIT sockets用于新建的TCP连接

    tcp_tw_reuse参数依赖于tcp_timestamps,Linux官方2.6以上的内核标志着该参数默认是开启的

    tcp_tw_reuse 中文字面理解,重复利用已存在TIME_WAIT状态的连接

    复用的条件如下

    1. 既然tcp_tw_reuse使用到tcp_timestmps,那说明一定和时间戳有关系,如果后发报文中的时间戳比之前缓存的时间戳大,将会从已建立的TIME_WAIT的连接选择进行数据传输

    2. 根据代码显示,TIME_WAIT状态的连接必须大于1秒才可复用

    连接复用的过程,如下图

    复用前的状态,主动关闭发起端收到被动关闭接收端的fin确认包后,同时发出ack包给被动关闭方,同时进入了TIME_WAIT状态,标准正常4次打招呼方式,这时发起新连接并使用复用此条TIME_WAIT状态的连接

    1. TIME_WAIT的连接被复用后,首先主动发起方,发送SYN包给接收端,此时发起方是SYN_SENT状态

    2. 但是接收端并不会应答该SYN包,并且同时忽略RST包,但是返回一个FIN给发起方

    3. 然后发起方发送一个RST包给接收方,促使对端跳过LASK-ACK阶段,然后在一秒之后,再次将初始发送的SYN至接收方,整个过程看上去没啥错误,只是在链路上延迟一会

    值得注意的是,如果发生了复用,则会在/proc/net/netstat中的字段TWRecycled累积

    • tcp_tw_recycle

    该内核参数默认情况下是关闭的,即值为0,开启值为1

    官方说明

    tcp_tw_recycle - BOOLEAN

    Enable fast recycling TIME-WAIT sockets. Default value is 0.It should not be changed without advice/request of technical experts.

    快速回收TIME_WAIT状态的连接

     

    tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4)[Translator’s Note: From the description of linux man tcp] Enable fast recycling of TIME-WAIT sockets. Enabling this option is not recommended since this causes

    problems when working with NAT (Network Address Translation).

    Enable fast recovery of sockets in TIME-WAIT state. This option is not recommended. In a NAT (Network Address Translation) network, a large number of TCP connection establishment errors will be caused.

    在2.4说明,在NAT环境中,此参数不再推荐开启,问题表现为如果遇到峰值的TCP连接会报错

     

    在4.12内核版本,官方release说明,将移除相关tcp_tw_recycle代码

    https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/networking/ip-sysctl.txt?h=v4.12 (技术文档已删除与之tw_recycle相关的说明文档)

    https://github.com/torvalds/linux/commit/4396e46187ca5070219b81773c4e65088dac50cc

    如何实现快速回收,如下

    1. 首先tw_recycle也需要依赖于tcp_timestampsg开启

    2. 具体快速回收时间与TCP中的RTO相关,相关的RTO时间可在(https://github.com/torvalds/linux/blob/v3.10/include/net/tcp.h)查看(MIN & MAX),根据(https://github.com/torvalds/linux/blob/v3.10/net/ipv4/tcp_minisocks.c  329)代码的意思理解,回收TIME_WAIT优先使用RTO的时间,否则按默认的TCP_TIMEWAIT_LEN的时间

    3. 一般这个时间差不多700ms,基本判断条件就是,如果存在TIME_WAIT就执行recycle

    解释NAT环境丢包的问题

    1. tcp_tw_recycle是必须依赖于tcp_timestamps,而tcp_timestamps则是解决PAWS的问题,所以PAWS的原则如下,RFC1323

      An additional mechanism could be added to the TCP, 
      a per-host cache of the last timestamp received from any connection. 
      This value could then be used in the PAWS mechanism to reject old duplicate segments from earlier incarnations of the connection, 
      if the timestamp clock can be guaranteed to have ticked at least once since the old connection was open. 
      This would require that the TIME-WAIT delay plus the RTT together must be at least one tick of the sender’s 
      timestamp clock. Such an extension is not part of the proposal of this RFC.

       原文解释了,TCP存在一种机制,per-host会缓存保留已建立连接的最新一个timestamp,而该timestamp要遵循PAWS的机制,具体作用就是如果下次接收的数据报文的时间戳早于记录的最后一个报文的时间戳,则直接丢弃该报文

    2. 当在NAT环境中,一般指多台服务器出公网都是由NAT地址转换的形式,则很难保证后端服务器时间是同步的,而引起的时间戳错乱,导致连接的数据报被drop

    总结

    关于该参数,既然在4.12版本的内核被移除,没必要再讨论,版本升级再也不会遇到这个问题

    参考文献


    https://perthcharles.github.io/2015/08/27/timestamp-NAT/

    https://vincent.bernat.ch/en/blog/2014-tcp-time-wait-state-linux

    https://blog.csdn.net/yunhua_lee/article/details/8146856

    https://blog.csdn.net/yunhua_lee/article/details/8146845

    https://blog.huoding.com/2012/01/19/142

    https://blog.huoding.com/2013/12/31/316

    https://www.cnblogs.com/zy09/p/13958915.html

    https://mp.weixin.qq.com/s?__biz=MzA3MzYwNjQ3NA==&mid=403232978&idx=1&sn=4ed396ac1999add1c866419bd62b0e75&scene=0#wechat_redirect

  • 相关阅读:
    Linux内存、Swap、Cache、Buffer详细解析
    深入浅出前端本地储存
    Javscript字符串常用方法总结
    Python优雅日志记录器-Loguru
    Flume推送数据到SparkStreaming案例实战和内幕源码解密
    SparkStreaming数据源Flume实际案例分享
    基于HDFS的SparkStreaming案例实战和内幕源码解密
    Scala和Java二种方式实战Spark Streaming开发
    StreamingContext、DStream、Receiver深度剖析
    案例动手实战并在电光石火间理解其工作原理
  • 原文地址:https://www.cnblogs.com/apink/p/15624532.html
Copyright © 2011-2022 走看看