我有一个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
答案 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 :(得分:1)
检查服务器上的负载。看起来服务器因负载而关闭连接 - exception on web-service call