`
shixiaomu
  • 浏览: 383081 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

tcp通道关闭时,发生了什么? time_wait close_wait

 
阅读更多
tcp通道关闭时,发生了什么?

   前段时间,同事发现一个采用Thrift TheadPoolServer作为TCP的服务出现了大量的CLOSE_WAIT状态的socket。当第一次遇到这种问题的时候,你可能会有如下的问题:

    什么是CLOSE_WAIT? 为什么会发生?
    还有其他类似状态我不知道的么?

其实,你真正想问的是:

    当tcp通道关闭时,发生了什么事情?
    我该怎么办?

TCP通道是一个连接,连接的两端都可以向通道里写数据或者从通道里读数据,连接的两端都可以发起关闭操作。整个TCP通道的关闭流程如下:

A(socketfd:10) <——–TCP Connction ———->B(socketfd:20)

    关闭A,则A向B发送FIN;
    B接受到FIN后,返回一个ACK,表明收到了关闭通知, 当B返回ACK后,状态就转变为CLOSE_WAIT(!)了,它在等待什么呢?等待程序显式(手动)的关闭socket B。如果打开B的程序在发出ACK后,没有做任何处理,那么它就一直处于CLOSE_WAIT中了。
    如果程序显式的关闭了B,那么B会向A发送一个FIN,然后B就处于LAST_ACK状态了;
    A在接受到B的FIN后,发出最后一个ACK,此时A就处于知名的TIME_WAIT状态了。TIME_WAIT时间一般会比较长。

如何避免CLOSE_WAIT? 太多的CLOSE_WAIT通常意味着你程序中存在着严重的问题:没有正确处理socket的关闭事件,去查看代码吧。

如何避免TIME_WAIT? 通常,这是一个不应该问的问题,应该先问自己,TIME_WAIT真的给你带来麻烦了么? TIME_WAIT是可靠性的保证机制,没有必要去避免它。但或许,你可以尝试一下使用RFC1323。如果某一端实在是有太多的TIME_WAIT而造成问题,我建议的策略是:

    尽量避免TIME_WAIT过多的一端主动关闭socket
    使用SocketPool,避免频繁创建/关闭socket


提到Thrift ThreadPoolServer有时候会出现较多的close wait状态,有朋友问我这是不是thrift的bug?写过Server比较多的同志们应该能意识到这个问题的原因,不值得说,可是我今天实在是太郁闷无聊了,我就写写我的想法吧。

我觉得这当然不能算是Thrift的Bug,如果出现了这样的问题,其实是因为错误的选择了Server的类型,错误的实现了Client,过于保守的Server Max Connection配置等等原因。

对于ThreadPoolServer而言,每一个客户端连接,Server端都需要提供一个固定的线程来维护,在空闲时,线程堵塞在read()操作,等待客户端数据的到来。Thrift ThreadPoolServer中使用的默认线程池是定长线程池,意味着Server端能提供的线程池数是有限的。当线程用完时,新的连接将不能得到Server殷勤的服务,它不会在乎你的生死,你必须等待。

举个例子:

    我有一个用Thrift ThreadPoolServer(使用SimpleThreadPool)实现的Server,最大支持100个连接,现在有100个客户端连接到我的Server。实现客户端的程序员都很在乎TCP连接建立的开销,因此,他们都维护了一个长连接。这个时候,如果有第101个客户端连接到Server了,会发生什么情况呢?

    Server会接受这个连接,连接成功建立;
    Server没有合适的线程来处理这个连接,于是将这个连接放到暂存列表;
    如果这个时候有线程空闲了,则一切顺利,这个线程将接管这个连接;
    但遗憾的是,我们没有空闲线程,所以这个连接一直处于空闲状态,直到客户端程序timeout(如果设置了timeout的话);
    连接timeout,意味着暂存列表里的连接已经失效了,此时对应的socket处于CLOSE_WAIT中(出现了本文开头的情况),遗憾的是,我们依然没有空闲的线程来处理这个连接,所以它一直处于CLOSE_WAIT中。
    终于,某一个时刻,有一个客户端关闭了连接,我们有了空闲线程,它去查看暂存列表。发现有一个socket fd,尝试去接管它,对这个fd执行read(),然后得到一个Connection Reset error,终于,我们可以优雅的关闭它了(CLOSE_WAIT结束)。
    以上就是全部的故事。

那么,要怎么办?

    1.如果连接数太多,为什么不用NonBlockingServer呢?Thrift有基于libevent的实现,虽然它的ThreadPool限制了NonblockingServer的性能,但是,你可以方便的实现一个存/取线程更高效的ThreadPool.
    2.你可以实现一个TimeoutCachedThreadPool来替代SimpleThreadPool.
    3.提高Max Connection的值.
分享到:
评论

相关推荐

    tcp连接出现close_wait状态?_tcp_close_

    当TCP连接出现“Close_Wait”状态时,通常意味着客户端已经关闭了发送方向服务器的数据传输,但服务器仍有数据需要发送给客户端。这个状态是TCP连接关闭过程中的一个中间状态,体现了TCP的四次挥手(FIN-ACK-FIN-ACK...

    TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题解决

    在 TCP 连接中,客户端和服务器端都可以处于不同的状态,例如 ESTABLISHED、CLOSE_WAIT、FIN_WAIT_1、FIN_WAIT_2、TIME_WAIT 等 trạng thái。 CLOSE_WAIT 状态是 TCP 连接中的一种状态,它表示服务器端已经收到了...

    CLOSE_WAIT网络连接无法释放问题解决

    CLOSE_WAIT是一个常见的TCP连接状态,指的是服务器端的连接在客户端关闭后还未释放的情况。这种情况经常出现于客户端主动断开连接,但服务器端没有正确关闭连接的情况下。这种情况可能会导致服务器端出现大量未释放...

    系统调优,你所不知道的TIME_WAIT和CLOSE_WAIT1

    CLOSE_WAIT状态发生在被动关闭连接的一方,即接收到对方的FIN包后,表示它已经收到了对方关闭连接的请求,但还需要等待自己这边的应用程序调用close来彻底关闭连接。大量CLOSE_WAIT状态可能意味着应用程序存在错误,...

    close_wait_0306 close_wait_0306 close_wait_0306 close_wait_0306

    当一个TCP连接处于`CLOSE_WAIT`状态时,这意味着本地主机已经接收到对之前发送的FIN(结束)标志的确认,但应用程序还没有关闭连接。在这个阶段,本地主机仍然可以接收数据,但不能发送更多的数据。通常,这表明...

    CLOSE_WAIT错误详解

    在TCP/IP协议栈中,CLOSE_WAIT是一个非常关键的连接状态,它涉及到客户端和服务器之间的通信。这个状态在处理网络连接时可能出现的问题时尤其重要。本文将深入探讨CLOSE_WAIT错误的含义、原因以及如何解决。 首先,...

    TIME_WAIT.rar_C-means_linux 网络状态_linux c wait_tcp_unix 网络编程

    在处理TCP连接时,需要特别关注close()函数的使用,因为它可能直接影响到TIME_WAIT状态的处理。 `c-means`可能是指一种基于C语言的聚类算法,虽然在这个上下文中没有直接关联,但如果你正在学习C语言编程,并试图将...

    Netstat命令详解如何关闭TIME_WAIT连接如何查看nginx的访问流量[归类].pdf

    8. TIME_WAIT:在关闭连接时,TCP 需要等待一段时间,以确保连接关闭的确认信息能够传输到对方。 9. LAST_ACK:在关闭连接时,TCP 需要等待一段时间,以确保连接关闭的确认信息能够传输到对方。 10. CLOSING:在关闭...

    Close_Wait问题相关资料

    在TCP/IP协议栈中,"Close_Wait"是一种连接状态,表示一个方向的连接已经关闭,而另一个方向仍然保持开放,等待应用层关闭。当服务器接收到客户端的FIN(结束)标志,它会进入Close_Wait状态,表示服务器已经接收到...

    TCP_SYNC基础

    如果对方在第三次握手的时候出问题,例如发 FIN 包的时候,不知道什么原因丢了这个包,客户端会一直处在 FIN_WAIT_2 状态,服务器端则处在 CLOSE_WAIT 状态。如果这种情况持续很长时间,系统可能会崩溃。 问题分析 ...

    10如何提升TCP四次挥手的性能?1

    3. `tcp_fin_timeout`:控制FIN_WAIT2和TIME_WAIT状态的超时时间。 4. `tcp_orphan_retries`:控制孤儿连接的重试次数,不只对孤儿连接有效,也可能影响非孤儿连接。 需要注意的是,错误配置这些参数可能会导致性能...

    tomcat-timewait-closewait.zip

    标题 "tomcat-timewait-closewait.zip" 暗示了这个压缩包可能包含与Tomcat服务器在处理TCP连接时遇到的“Time_wait”和“Close_wait”状态相关的问题和解决方案。这两个术语是TCP/IP协议栈中的关键概念,尤其在高...

    tcp连接状态详解 描述了tcp协议常用的命令

    最后,被动关闭的一方会由 CLOSE_WAIT 状态转移到 LAST_ACK 状态,发送 FIN 给对方,同时在接收到 ACK 时进入 CLOSED 状态。 TIME_WAIT 状态是 TCP 连接状态中最复杂的状态。它可以由多个状态转移到达,包括 FIN_...

    tcp状态解析和windowsio说明

    主动关闭可能会经过FIN_WAIT_1、FIN_WAIT_2、TIME_WAIT状态,而被动关闭则经历CLOSE_WAIT、LAST_ACK状态。在处理TIME_WAIT状态时,需要注意避免端口冲突,可以使用SO_REUSEADDR选项来允许立即重用套接字地址,或者...

    四次挥手中收到乱序的FIN包如何处理542 - 557

    客户端和服务器之间的 TCP 连接,在关闭连接时,需要经历四个阶段:FIN_WAIT_1、CLOSE_WAIT、FIN_WAIT_2 和 TIME_WAIT。其中,FIN_WAIT_2 状态是指客户端已经发送了 FIN 报文,并等待服务器的确认响应。 现在,假设...

    hadoop面试题

    - 在TCP连接的终止过程中,TIME_WAIT状态的存在是为了确保连接两个方向的可靠终止,即所谓的“全双工关闭”。当一方发送了最后一个确认(ACK)之后,它必须进入TIME_WAIT状态,以防万一这个ACK丢失导致对方重新发送...

    TCP_IP算法.rar_C++算法_TCP/IP协议_TCP_IP_网络 协议 源码_网络协议

    源码分析可能涉及理解TCP的状态机,如CLOSED、LISTEN、SYN_SENT、SYN_RCVD、ESTABLISHED、FIN_WAIT_1、FIN_WAIT_2、CLOSE_WAIT、CLOSING、LAST_ACK、TIME_WAIT等状态及其转换。同时,还会涉及IP头部的解析,以及错误...

Global site tag (gtag.js) - Google Analytics