多个完整的HTTP请求陷入TCP CLOSE_WAIT状态

时间:2009-09-08 14:14:32

标签: java http tcp sockets

我有一个基于Java和Tomcat的服务器应用程序,它启动许多到其他网站的出站HTTP请求。我们使用Jakarta的HTTP核心/客户端库,这是最新版本。

服务器在某些时候锁定,因为它的所有工作线程都在试图关闭已完成的HTTP连接。使用'lsof'显示一堆插在TCP CLOSE_WAIT状态的套接字。

对所有人甚至是大多数连接都不会发生这种情况。事实上,我之前看过它并通过确保设置Connection:Close响应头来解决它。所以这让我觉得它可能是远程服务器的不良行为。

自从我将应用程序移至全新的服务提供商 - 不同的操作系统,网络状况后,它可能会再次出现。

但是,我仍然不知道我能做些什么,如果有的话,可以解决这个问题。有些人在网上闲逛并没有发现我还没有做过的事情。我以为我会问是否有人见过并解决了这个问题?

2 个答案:

答案 0 :(得分:2)

我不确定你对TCP有多了解。当TCP客户端处于CLOSE_WAIT状态并且收到ESTABLISHED数据包时,它将以FIN状态结束。 CLOSE_WAIT状态意味着它正在等待从应用程序层接收close命令 - 在这种情况下,这意味着它正在等待在套接字上调用close()

所以,我的猜测是在工作线程中调用close()将解决问题。或者你已经这样做了吗?

答案 1 :(得分:2)

我相信我可能找到了一个解决方案 - 至少,这些变化似乎已经使问题消失了。

  • 在完成从InputStream读取后调用HttpEntity.consumeContent(),仔细检查内容是否被消耗,框架是否释放连接
  • 为了更好的衡量,我在此之后调用ClientConnectionManager.closeExpiredConnections()和ClientConnectionManager.closeIdleConnections(0L,TimeUnit.MILLISECONDS),按下框架以立即释放它所做的任何事情。这可能有点矫枉过正。

好的以上并没有完全解决问题。最后,我不得不使用SingleClientConnManager,并为每个请求创建并关闭它。这样做了。我认为这是确保连接关闭所需的。