"连接重置"使用SOAP时

时间:2016-03-04 08:36:28

标签: java web-services soap jax-ws

我有一个REST服务,有些客户得到了#34;连接重置"错误。但SOAP是无状态的,那么为什么它只是简单地重新连接并重新发送请求呢?它实际上在我的用例中发送了多个消息,但第一个失败了,这只是从服务器获取一些配置数据。这是我需要配置的吗?客户端是否应该以编程方式尝试重新发送消息?有些用户多次尝试相同的结果。

在过去的几年中从未发生过,但现在我得到了一些关于这个问题的报告 客户端使用javax.xml.ws.Service的实现,而不仅仅是原始套接字。但即使我使用JAX,我也会得到低级错误。它由WebServiceException包裹,但这并不能帮我解决这个问题。 客户端都使用Java 8.它是Update 66或Update 74.

我自己无法重现问题,我只有用户的日志文件。

这里是完整的堆栈跟踪:

javax.xml.ws.WebServiceException: java.net.SocketException: Connection reset
    at com.sun.xml.internal.ws.transport.http.client.HttpClientTransport.readResponseCodeAndMessage(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.createResponsePacket(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.process(Unknown Source)
    at com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.processRequest(Unknown Source)
    at com.sun.xml.internal.ws.transport.DeferredTransportPipe.processRequest(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Unknown Source)
    at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Unknown Source)
    at com.sun.xml.internal.ws.client.Stub.process(Unknown Source)
    at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(Unknown Source)
    at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(Unknown Source)
    at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(Unknown Source)
    at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(Unknown Source)
    at com.sun.proxy.$Proxy31.getLimits(Unknown Source)
    at xxxxxxxxxxxxx.SOAPServerAdapter.connect(Unknown Source)
    at xxxxxxxxxxxxxxxxxxxx(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at sun.security.ssl.InputRecord.readFully(Unknown Source)
    at sun.security.ssl.InputRecord.read(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
    at sun.security.ssl.AppInputStream.read(Unknown Source)
    at java.io.BufferedInputStream.fill(Unknown Source)
    at java.io.BufferedInputStream.read1(Unknown Source)
    at java.io.BufferedInputStream.read(Unknown Source)
    at sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source)
    at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
    at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at java.net.HttpURLConnection.getResponseCode(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
    ... 18 more

2 个答案:

答案 0 :(得分:2)

原来它是关于IPv4和IPv6的。我没有足够的知识来提供完美的答案,但我可以在这里发布他们告诉我的内容。也许这有助于其他有相同问题的开发者/用户。

因此,有些客户端会发生意外的连接重置,而且与通常情况下的服务器负载无关。

如果客户端的ISP试图远离IPv4,它们将为每个用户提供唯一的IPv6地址(请注意,ISP可能会逐渐执行此操作)。除了本地使用的IPv4之外,它们不再具有每个客户端的IPv4地址,因为大多数仍然使用类似于192.168.0.0/24的LAN。

而不是传统的IPv4,他们使用一些transaction mechanism(例如Dual-Stack Lite)。那些客户无法直接访问IPv4互联网。因此,如果您的服务器仅支持IPv4,那么他们可能会遇到使用代理时遇到的类似问题。它们将IPv4数据包封装在IPv6数据包中,用于通信的某些部分。来自维基百科:"原始IPv4数据包被恢复,NAT在IPv4数据包上执行,并被路由到公共IPv4互联网。"

我真的不知道这里出了什么问题。也许NAT用完了地址/端口或类似的东西。或者过程需要很长时间,连接会被通信中涉及的某个节点重置。

所以有两件事要做:

  1. 告知ISP有关这些问题的信息。它们可能会帮助您跟踪确切的问题并帮助他们的客户,以便他们可以使用您的服务。为此,您需要知道具有"连接重置"的用户的ISP。问题。将它们发送到https://www.whoismyisp.org/或类似网站。
  2. 尽快升级到IPv6。您的服务器可以同时使用这两个版本的协议。

答案 1 :(得分:1)

检查服务器上的负载。看起来服务器因负载而关闭连接 - exception on web-service call