有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用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

共 (2) 个答案

  1. # 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没有地址/端口或类似的东西。或者该过程花费的时间太长,导致通信中涉及的某个节点重置了连接

    所以有两件事要做:

    1. 将这些问题通知ISP。他们可能会帮助您追踪确切的问题,并帮助他们的客户使用您的服务。为此,您需要了解出现“连接重置”问题的用户的ISP。将它们发送到https://www.whoismyisp.org/或类似站点
    2. 请尽快升级到IPv6。您的服务器可以同时使用协议的两个版本