是什么原因导致套接字ConnectException:连接超时?

我们有一个Webstart客户端,它通过使用HTTPS通过HTTPS发送序列化对象来与服务器通信java.net.HttpsURLConnection

在本地计算机和办公室中的测试服务器上,一切都可以正常工作,但是我遇到了一个非常非常奇怪的问题,该问题仅在生产和登台服务器上出现(偶尔发生)。我知道这些服务器与我们办公室中的服务器之间的主要区别在于它们位于其他位置,并且与它们之间的客户端-

服务器通信速度相当慢,但在此之前的生产中也能正常工作很长时间。

无论如何,这是正在发生的事情:

  • 客户端在设置选项(例如读取超时)和属性(例如在Content-Type上)后HttpURLConnection,调用getOutputStream()它以获取要写入的流。
  • 在这一点上,据我所知,客户端挂起了一段时间。
  • 然后,客户端引发以下异常:

    java.net.ConnectException:连接超时:connect

    在java.net.PlainSocketImpl.socketConnect(本地方法)

    在java.net.PlainSocketImpl.doConnect(未知来源)

    在java.net.PlainSocketImpl.connectToAddress(未知来源)

    在java.net.PlainSocketImpl.connect(未知源)

    在java.net.SocksSocketImpl.connect(未知源)

    在java.net.Socket.connect(未知源)

    在com.sun.net.ssl.internal.ssl.SSLSocketImpl.connect(未知来源)

    在com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.connect(未知来源)

    在sun.net.NetworkClient.doConnect(未知来源)

    在sun.net.www.http.HttpClient.openServer(未知来源)

    在sun.net.www.http.HttpClient.openServer(未知来源)

    在sun.net.www.protocol.https.HttpsClient。(来源不明)

    在sun.net.www.protocol.https.HttpsClient.New(未知来源)

    在sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(未知来源)

    在sun.net.www.protocol.http.HttpURLConnection.plainConnect(未知源)

    在sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(未知源)

    在sun.net.www.protocol.http.HttpURLConnection.getOutputStream(未知源)

    在sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(未知来源)

请注意,这不是一个SocketTimeoutException,如果超时在可以建立连接之前超时,该connect()方法将HttpURLConnection表示抛出该异常。另外,发生这种情况时,我可以打电话给conn.getResponseCode()我,并获得200的响应码。

  • 在服务器端,EOFException会在ObjectInputStream的构造函数中抛出an ,该构造函数尝试读取序列化标头,但由于客户端始终OutputStream无法写入而失败。

如果有帮助,这里是在调用HttpsURLConnection之前进行的调用getOutputStream()(经过编辑以仅显示正在进行的调用,而不是执行此操作的整个代码结构):

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

conn.setUseCaches(false);

conn.setReadTimeout(30000);

conn.setRequestProperty("Cookie", cookie);

conn.setDoOutput(true);

conn.setRequestProperty("Content-Type", "application/x-java-serialized-object");

conn.getOutputStream();

关键是,我不知道这是怎么发生的,特别是考虑到它只是 偶尔 发生(我无法说出明确的活动模式),甚至只有在客户端和客户端之间(相对)高延迟时才发生服务器。

鉴于到目前为止我已经找到了什么java.net.ConnectException: Connect timed

out,我想知道这是否不是我们的服务器正在运行的网络上的某些网络或防火墙问题…但是鉴于请求,这对我来说没有多大意义显然已经到达了servlet。此外,在同一网络上运行的其他应用程序也未报告类似问题。

有谁知道这可能是什么原因,甚至我应该调查什么?

回答:

我们在与您类似的情况下遇到了这些情况。通常在高负载下,不容易在测试中复制。尚未解决,但这是我们经历的步骤。

如果是防火墙问题,我们将收到“连接被拒绝”或SocketTimeout异常。

1)您能否在服务器上的访问日志中跟踪这些请求-

它们显示的HTTP状态为200还是404或其他?在我们的例子中,服务器(在本例中为IIS)日志显示客户端关闭了连接而不是服务器。这是一个谜。

如果客户总是得到一个200,那么服务器实际上已经发回了一些回应,但我怀疑的响应字节大小(如果这是记录在访问日志)

为该请求。

如果显示的响应大小相同,则您有一个(可能不合理)的条件,即服务器 实际上正确响应了, 但客户端未获得响应,因为连接在两者之间终止。

2)网络管理员团队查看了TCP / IP流量,以确定哪个端(或中间路由器)正在终止HTTP / TCP-

IP对话。一旦我们了解了终止连接的一端,便可以查看原因。足够了解的人可以窥探

3)服务器上是否配置/限制了最大数量的请求-这是否限制了您的连接?

4)是否有任何中间负载均衡器可以丢弃请求?

我们想做的但还没有完成的另一件事是在客户端和服务器之间创建一条静态路由,以减少两者之间的跳数,并确保没有与网络相关的连接断开。参见http://en.wikipedia.org/wiki/Static_routing

5)另一个建议是也设置ConnectTimeout以查看它们是否可以使用更高的值。

您可能想尝试conn.getErrorStream()

如果连接失败但服务器仍发送有用数据,则返回错误流。如果未连接连接,或者服务器连接时没有错误,或者服务器有错误但没有发送错误数据,则此方法将返回null。

6)也可以尝试间隔5秒在服务器上进行一组线程转储,以查看是否有任何线程在服务器上显示这些传入请求。

从今天开始,我们学会了解决这个问题,因为在每天的40万个请求中,总计失败率为200-300,这是0.00075%

以上是 是什么原因导致套接字ConnectException:连接超时? 的全部内容, 来源链接: utcz.com/qa/430319.html

回到顶部