• 关于TCP主动关闭连接中的wait_timeout


    首先我们先来回顾一下tcp关闭连接的过程:

    假设A和B连接状态为EST,A需要主动关闭:

    A发送FIN给B,并将状态更改为FIN_WAIT1,

    B接收到FIN将状态更改为CLOSE_WAIT,并回复ACK和FIN

    A收到ACK后将状态更改为FIN_WAIT2,收到FIN后,更改状态为WAIT_TIMEOUT并给B返回ACK

    B收到ACK后,将关闭自己的链接CLOSE。

    问题就在此时,A将处于WAIT_TIMEOUT状态长达2MSL时常(RFC793定义了MSL为2分钟,Linux设置成了30s),为什么会有这个状态存在呢?为什么不直接进入close状态呢?

    主要有两个原因:

    1、TIME_WAIT确保有足够的时间让对端收到了ACK,如果被动关闭的那方没有收到Ack,就会触发被动端重发Fin,一来一去正好2个MSL;

    2、有足够的时间让这个连接不会跟后面的连接混在一起(如果连接被重用了,那么这些延迟收到的包就有可能会跟新连接混在一起)。

        我们经常就会在服务器上发现有很多的wait_timeout,特别常见的就是http服务器,从上面的描述来看,这个状态应该是主动关闭的一方,才会有的状态,我们有没有想过,就是为什么服务器端会主动断开连接呢?不应该是客户端主动断开吗?

        据说,其实在最初的http协议,服务器在发送完客户端需要的内容后,就主动关闭连接,因为当时的客户端,需要等待所有效果渲染完毕,才会主动断开连接,为了照顾当时性能低下的服务器,更好的服务其他客户,才在协议中这样规定,说到底就是http协议太老了,所以Google才会推他的SPDY协议。

       

        那么,如何解决这种问题呢?

        网上有两种方法,设置tcp_tw_reuse和tcp_tw_recycle,但是这两种方法据说都存在一些危险性:

    具体引用coolshell的blog:

      • 关于tcp_tw_reuse。官方文档上说tcp_tw_reuse 加上tcp_timestamps(又叫PAWS, for Protection Against Wrapped Sequence Numbers)可以保证协议的角度上的安全,但是你需要tcp_timestamps在两边都被打开(你可以读一下tcp_twsk_unique的源码 )。我个人估计还是有一些场景会有问题。
      • 关于tcp_tw_recycle。如果是tcp_tw_recycle被打开了话,会假设对端开启了tcp_timestamps,然后会去比较时间戳,如果时间戳变大了,就可以重用。但是,如果对端是一个NAT网络的话(如:一个公司只用一个IP出公网)或是对端的IP被另一台重用了,这个事就复杂了。建链接的SYN可能就被直接丢掉了(你可能会看到connection time out的错误)(如果你想观摩一下Linux的内核代码,请参看源码 tcp_timewait_state_process)。

        既然都这么危险,该怎么解决呢?目前我能想到的就是增加keepalive的时长,等着客户端来断开连接,但是有时候浏览器可能会设置断开的时间更长……

    其实,TIME_WAIT表示的是你主动断连接,所以,这就是所谓的“不作死不会死”。试想,如果让对端断连接,那么这个破问题就是对方的了,呵呵。另外,如果你的服务器是于HTTP服务器,那么设置一个HTTP的KeepAlive有多重要(浏览器会重用一个TCP连接来处理多个HTTP请求),然后让客户端去断链接(你要小心,浏览器可能会非常贪婪,他们不到万不得已不会主动断连接)。

        不知道大家在服务器上,是怎么解决这个问题的?

    引用链接:

    http://coolshell.cn/articles/11564.html

    https://www.zhihu.com/question/24338653

  • 相关阅读:
    CSS 中 Font-Family 中英文对照表
    0号首页,移动应用快捷门户
    身边的大数据和我们的着手点
    php单例模式
    原生JS实现ajax与ajax的跨域请求
    two.js之实现动画效果
    H5中的拖放
    简说chart2.4的应用,以及Uncaught ReferenceError : require is not defined的解决
    JS中的作用域以及全局变量的问题
    JavaScript 框架------------AngularJS(下)
  • 原文地址:https://www.cnblogs.com/agostop/p/5222436.html
Copyright © 2020-2023  润新知