对CLOSE_WAIT状态中的连接进行故障排除

时间:2011-04-12 13:52:43

标签: java sockets tcp weblogic netstat

我在Windows上运行的是WebLogic 11g中的Java应用程序,几天后,它变得没有响应。我注意到的一个可疑症状是,即使服务器处于空闲状态,大量连接(大约3000个)也会显示在netstat中,并具有CLOSE_WAIT状态。由于应用程序服务器正在管理客户端连接,因此我不确定是什么导致了这种情况。我们还进行了许多环回到同一服务器的Web服务调用,但我相信这些连接会正常关闭。还有什么可能导致这种情况以及如何解决这样的问题呢?

6 个答案:

答案 0 :(得分:18)

我一直有同样的问题,我一直在研究套接字以摆脱这个问题。

让我说几句,但在我必须说我不是Java程序员之前。

我不会解释close_wait是什么,因为Brian White已经说了应该说的一切。

为避免close_wait,您需要确保服务器在发回响应后不关闭连接,因为任何先断开连接的服务器都会在close_wait和time_wait中卡住。因此,如果您的服务器卡在close_wait中,它会在发送响应后告诉我它正在断开连接。

你应该通过做一些事情来避免这种情况。

1 - 如果您的客户端应用程序未使用http 1.1协议,则必须将其设置为使用该协议,因为'keep-alive http标头选项。

2 - 如果您的客户端正在运行http 1.1并且不起作用,或者,如果您必须使用http 1.0,则应设置连接请求标头属性:

connection: keep-alive

这告诉服务器在完成请求后客户端和服务器都不应断开连接。通过这样做,您的服务器在收到每个请求后都不会断开连接。

3 - 在您的客户端中,重用您的套接字。例如,如果要在循环中创建大量套接字客户端,则应创建一次套接字,并在每次需要发送请求时使用它。我在我的应用程序中使用的方法是使用套接字池并获得一个可用的套接字(已连接到服务器并且它具有keep-alive属性)。然后我使用它,当我完成后,我把它放回池中以便可重复使用。

4 - 如果您确实需要在发送请求后断开连接,请确保客户端执行此操作并保留connection: keep-alive

是的,当你在服务器端有很多close_waits或time_waits时,你可能会遇到问题。

查看此[link] [1],其中解释keep-alive是什么。

我希望这很有帮助。有了这些东西,我设法解决了我的问题。

[1]:http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Persistent连接

答案 1 :(得分:17)

CLOSE_WAIT是远程主机发送FIN(关闭它的连接)时本地TCP状态机所处的状态,但本地应用程序没有完成相同的操作并发送了回复FIN。虽然客户端无法接收数据,但本地机器仍然可以在此时发送数据(除非它只在连接上关闭了一半)。

当远程主机关闭(发送FIN)时,本地应用程序将获得某种事件(它是基本C库中套接字上的“读取”事件)但是从该连接读取将返回错误表示连接已关闭。此时,本地应用程序应该关闭连接。

我对Java知之甚少,对WebLogic一无所知,但我认为应用程序可能无法正确处理读取错误,因此永远不会关闭连接。

答案 2 :(得分:4)

CLOSE_WAIT状态表示另一方已启动连接关闭,但本地应用程序尚未关闭套接字。

听起来您的本地应用程序中存在错误。

答案 3 :(得分:2)

问题是在webLogic中将“使用JSSE SSL”设置为true时触发的错误。使用WebLogic自己的SSL实现而不是JSSE对我们的应用程序来说不是问题,因此我只是取消选中该设置并且问题消失了。

答案 4 :(得分:1)

我找到了关于CLOSE_WAIT堆积的引用:“有什么东西阻止了进展 发生在HTTP会话中(我们被卡住所以永远不会最终调用close),或者引入了一些阻止套接字被关闭的bug。有很多方法可以实现。“

想一想:在处理请求时,您的应用程序是否有任何问题?还是WebLogic本身?

检查:你能不能进行Java线程转储(在Oracle JVM for Linux上使用kill -SIGQUIT),试着看看你的线程是否真的被卡住了?

检查客户端:首先,找出连接到CLOSE_WAIT套接字的客户端的IP地址或主机名。然后,查看这些客户端是否发生任何可疑事件。

答案 5 :(得分:1)

这可能意味着您没有通过accept()调用在套接字上调用“close”。