使用SOAP时的java“连接重置”
我有一个REST服务,一些客户端出现“连接重置”错误。但是SOAP是无状态的,所以为什么它不简单地重新连接并重新发送请求呢?在我的用例中,它实际上发送了多条消息,但第一条消息失败,这只是为了从服务器获取一些配置数据。这是我需要配置的吗?客户端是否应该以编程方式尝试重新发送消息?一些用户尝试了多次,结果相同
这在过去几年中从未发生过,但现在我收到了一些关于这个问题的报告
客户端在javax.xml.ws.Service
的实现中使用,而不仅仅是原始socket。但即使我使用JAX,我也会得到低级错误。它由WebServiceException
包装,但这并不能真正帮助我解决这个问题。
客户端都使用Java8。要么是更新66,要么是更新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
# 1 楼答案
原来是关于IPv4和IPv6的。我没有足够的知识来给出一个完美的答案,但我可以把他们告诉我的东西贴在这里。也许这可以帮助其他有同样问题的开发人员/用户
因此,有些客户端会出现意外的连接重置,这与服务器负载无关
如果客户端的ISP试图脱离IPv4,他们将为每个用户提供一个唯一的IPv6地址(请注意,ISP可能会逐渐这样做)。除了本地使用的IPv4之外,他们实际上不再为每个客户机提供IPv4地址,因为大多数客户机的LAN仍然使用类似192.168.0.0/24的地址
它们使用一些transaction mechanism(例如双栈Lite)来代替传统的IPv4。这些客户端无法直接访问IPv4 internet。因此,如果您的服务器只支持IPv4,那么它们可能会遇到与使用代理时类似的问题。它们将IPv4数据包封装在IPv6数据包中,用于通信的某些部分。来自维基百科:“原始IPv4数据包被恢复,NAT在IPv4数据包上执行,并被路由到公共IPv4互联网。”
我真的不知道这里出了什么问题。可能NAT没有地址/端口或类似的东西。或者该过程花费的时间太长,导致通信中涉及的某个节点重置了连接
所以有两件事要做:
# 2 楼答案
检查服务器上的负载。看起来服务器正在关闭连接,因为加载-exception on web-service call