【发布时间】:2010-10-21 16:57:04
【问题描述】:
我有一个基于 Web 的应用程序和一个客户端,它们都是用 Java 编写的。值得一提的是,客户端和服务器都在 Windows 上。客户端通过Apache HttpClient 发出HTTP GET。服务器最多阻塞一分钟,如果在那一分钟内没有消息到达客户端,则服务器返回 HTTP 204 No Content。否则,一旦为客户端准备好消息,就会返回带有 HTTP 200 OK 的正文。
这让我感到困惑:间歇性地对于特定的客户端子集——总是具有明显不稳定的网络连接的客户端——客户端发出 GET,服务器接收并处理 GET,但是客户永远坐着。为客户端启用调试日志,我看到 HttpClient 仍在等待响应的第一行。
服务器上没有抛出异常,至少没有任何地方记录,不是由Tomcat,不是由我的webapp。根据调试日志,服务器成功响应客户端的各种迹象。但是,客户没有收到任何东西的迹象。客户端在HttpClient.executeMethod 中无限期挂起。这在会话超时并且客户端采取导致另一个线程发出 HTTP POST 的操作后变得很明显。当然,POST 失败是因为会话已过期。在某些情况下,从会话到期到客户端发出 POST 并发现这一事实之间已经过去了 小时。在整个过程中,executeMethod 仍在等待 HTTP 响应行。
当我使用 WireShark 查看线路级别的实际情况时,不会发生此故障。也就是说,对于特定客户端,此故障将在几个小时内发生,但当 WireShark 在两端运行时,这些相同的客户端将运行一夜,14 小时,而不会出现故障。
有没有其他人遇到过这样的事情?到底是什么原因造成的?我认为即使在短期网络故障中,TCP/IP 也能保证数据包的传递。如果我设置了 SO_TIMEOUT 并在超时时立即重试请求,重试总是成功的。 (当然,我先abort这个超时请求,然后释放连接,保证会使用新的socket。)
想法?想法?是否有一些适用于 Java 的 TCP/IP 设置或 Windows 中的注册表设置可以对丢失的数据包启用更积极的 TCP/IP 重试?
【问题讨论】:
-
听起来观察正在改变结果 -> Heisenbug -> 线程有问题。在这种情况下,听起来有人太快(我会把钱放在 HttpClient 上)并因此而陷入僵局。您可能遇到了 HttpClient 本身的错误,希望其他人可以提供更多帮助并帮助您解决此问题。