zoukankan      html  css  js  c++  java
  • TCP TIME_WAIT和CLOSE_WAIT

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11484451.html

    使用如下指令查看当前Server的TCP状态

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

    常用的三个状态

    • ESTABLISHED 表示正在通信
    • TIME_WAIT 表示主动关闭
    • CLOSE_WAIT 表示被动关闭

    主动关闭的一方发出 FIN 包,被动关闭的一方响应 ACK 包,此时,被动关闭的一方就进入了 CLOSE_WAIT 状态。

    如果一切正常,稍后被动关闭的一方也会发出 FIN 包,然后迁移到 LAST_ACK 状态。

    通常,CLOSE_WAIT 状态在服务器停留时间很短,如果你发现大量的 CLOSE_WAIT 状态,那么就意味着被动关闭的一方没有及时发出 FIN 包,

    一般有如下几种可能:

    • 程序问题:代码层面遗漏或者死循环之类的,没有 close 相应的 socket 连接。
    • 响应太慢:对方已经 timeout 了,本方还忙于耗时处理逻辑,导致 close 被延后。
    • BACKLOG 太大:队列堆积严重,导致多余的请求来不及消费就被关闭了。

    在终止连接的四次握手状态中,有一个特别要注意的状态TIME_WAIT。这个状态是主动关闭方在收到被关闭方的FIN后会处于并“长期”处于的一个状态,

    TIME_WAIT状态存在的理由

    1. 可靠地实现TCP全双工连接的终止 

    TCP协议在关闭连接的四次握手过程中,最终的ACK是由主动关闭连接的一端(后面统称A端)发出的,如果这个ACK丢失,对方(后面统称B端)将重发出最终的FIN,因此A端必须维护状态信息(TIME_WAIT)允许它重发最终的ACK。如果A端不维持TIME_WAIT状态,而是处于CLOSED 状态,那么A端将响应RST分节,B端收到后将此分节解释成一个错误。 

    因而,要实现TCP全双工连接的正常终止,必须处理终止过程中四个分节任何一个分节的丢失情况,主动关闭连接的A端必须维持TIME_WAIT状态 。 

    2. 允许老的重复分节在网络中消逝 

    TCP分节可能由于路由器异常而“迷途”,在迷途期间,TCP发送端可能因确认超时而重发这个分节,迷途的分节在路由器修复后也会被送到最终目的地,这个迟到的迷途分节到达时可能会引起问题。在关闭“前一个连接”之后,马上又重新建立起一个相同的IP和端口之间的“新连接”,“前一个连接”的迷途重复分组在“前一个连接”终止后到达,而被“新连接”收到了。为了避免这个情况,TCP协议不允许处于TIME_WAIT状态的连接启动一个新的可用连接,因为TIME_WAIT状态持续2MSL,就可以保证当成功建立一个新TCP连接的时候,来自旧连接重复分组已经在网络中消逝。

    TCP状态转换图

    三次握手与四次挥手

    一般不到万不得已的情况也不会去查看网络状态,如果服务器出了异常,百分之八九十都是下面两种情况:

    1.服务器保持了大量TIME_WAIT状态

    TIME_WAIT状态可以通过优化服务器参数得到解决,因为发生TIME_WAIT的情况是服务器自己可控的,要么就是对方连接的异常,要么就是自己没有迅速回收资源,总之不是由于自己程序错误导致的。

    2.服务器保持了大量CLOSE_WAIT状态

    如果一直保持在CLOSE_WAIT状态,那么只有一种情况,就是在对方关闭连接之后服务器程序自己没有进一步发出ack信号。

    换句话说,就是在对方连接关闭之后,程序里没有检测到,或者程序压根就忘记了这个时候需要关闭连接,于是这个资源就一直被程序占着。这种情况,通过服务器内核参数也没办法解决,服务器对于程序抢占的资源没有主动回收的权利,除非终止程序运行。

    CLOSE_WAIT和TIME_WAIT的区别

    举个例子来说明:服务器A是一台爬虫服务器,它使用简单的HttpClient去请求资源服务器B上面的apache获取文件资源,正常情况下,如果请求成功,那么在抓取完资源后,服务器A会主动发出关闭连接的请求,这个时候就是主动关闭连接,服务器A的连接状态我们可以看到是TIME_WAIT。如果一旦发生异常呢?假设请求的资源服务器B上并不存在,那么这个时候就会由服务器B发出关闭连接的请求,服务器A就是被动的关闭了连接,如果服务器A被动关闭连接之后程序员忘了让HttpClient释放连接,那就会造成CLOSE_WAIT的状态了。

    所以如果将大量CLOSE_WAIT的解决办法总结为一句话那就是:查代码,因为问题出在服务器程序里。

    Reference

    https://blog.csdn.net/shootyou/article/details/6622226

  • 相关阅读:
    Javascript内容整理——BOM
    前端实现excel报表,vue+luckysheet
    代码转图片 的一个好用网站
    推荐一个非常好用前端在线编辑器!!! 一点都不卡
    前端常用的一些网站
    vue中使用moment,如何按需打包?
    better-scroll
    时间线
    碎纸屑动画
    动画
  • 原文地址:https://www.cnblogs.com/agilestyle/p/11484451.html
Copyright © 2011-2022 走看看