【问题标题】:java.net.SocketException: Connection reset on Tomcat Onlyjava.net.SocketException:仅在 Tomcat 上重置连接
【发布时间】:2016-09-19 12:11:02
【问题描述】:

我知道以前有人问过这个问题,并且我尝试过查看至少 30 个关于 stackoverflow 的解决方案,如果不是更多的话,但到目前为止没有任何效果。

我有一个 tomcat 服务器,它正在查询 REST api 以获取和存储数据。这是为了避免每次我的应用程序想要加载数据时都必须向远程 API 查询数据。数据仅偶尔更改一次,因此需要努力。 我有一个简单的代码来连接

final URL url = new URL("https://remote.site.com/api/request?apikey=<some-key>");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.connect();
final InputStream inputStream = connection.getInputStream();
final InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
final Gson gson = new Gson();
MyJSONResponse myJSONResponse = gson.fromJson(inputStreamReader, MyJSONResponse.class);

当我从 MacBook 上的 Tomcat7 服务器运行此代码时,它运行得非常好。我得到了 JSON,一切都是 hunky dory。所以我继续在我的 Ubuntu 上的 Tomcat7 服务器内部运行它,我几乎立即得到了 SocketException。

我承认数据有点长,但我希望它在抛出这个异常之前等待几秒钟。但是这个异常抛出就行了

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

这对我来说没有意义。 为了进一步测试,我制作了一个只包含这些代码行的类程序,并打印出我从远程 api 获得的输入流,然后在我的 Ubuntu 机器上运行它,它运行得非常好。所以 Ubuntu 盒子和互联网连接没有问题。 Tomcat 服务器似乎在这里搞砸了。 我一直在尝试通过重置连接来做 4-5 个小时的多件事,而不是在 finally 块和其他事情中关闭它,但似乎没有任何效果。 任何帮助将不胜感激。 谢谢

编辑: 为超时添加日志:

*** Init called
May 22, 2016 11:23:21 PM org.apache.http.impl.execchain.RetryExec execute
INFO: I/O exception (java.net.SocketException) caught when processing request to {s}->https://www.data.gov.in:443: Connection reset
May 22, 2016 11:23:21 PM org.apache.http.impl.execchain.RetryExec execute
INFO: Retrying request to {s}->https://www.data.gov.in:443
May 22, 2016 11:23:22 PM org.apache.http.impl.execchain.RetryExec execute
INFO: I/O exception (java.net.SocketException) caught when processing request to {s}->https://www.data.gov.in:443: Connection reset
May 22, 2016 11:23:22 PM org.apache.http.impl.execchain.RetryExec execute
INFO: Retrying request to {s}->https://www.data.gov.in:443
May 22, 2016 11:23:24 PM org.apache.http.impl.execchain.RetryExec execute
INFO: I/O exception (java.net.SocketException) caught when processing request to {s}->https://www.data.gov.in:443: Connection reset
May 22, 2016 11:23:24 PM org.apache.http.impl.execchain.RetryExec execute
INFO: Retrying request to {s}->https://www.data.gov.in:443
java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:196)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
    at sun.security.ssl.InputRecord.read(InputRecord.java:480)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1344)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1371)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
    at com.soulpatch.jersey.DataFetcher.init(DataFetcher.java:47)
    at com.soulpatch.jersey.DataFetcher.getBloodBanks(DataFetcher.java:86)
    at com.soulpatch.jersey.resources.BloodBanksResource.getBloodBanks(BloodBanksResource.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

【问题讨论】:

  • 不是,是connection.connect()抛出的。

标签: java rest tomcat7 socketexception


【解决方案1】:

看来,我访问的网站是罪魁祸首。当我点击https://www.google.com 时,我的服务器似乎工作正常。 所以我相信这与我的 Tomcat 上的 SSL 证书解析有关。

【讨论】:

  • 不,这与目标服务器在 SSL 握手中速度慢有关。与您的Tomcat无关。我怀疑证书还没有收到。您的超时非常激进。我至少会加倍。
  • 我继续使用以下代码将超时时间增加到 30 秒。 (我改成了 apache HttpClient):final HttpClient client = HttpClients.createDefault(); final RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(30000) .setConnectTimeout(30000) .build(); 它仍然给我同样的错误。我已经用整个堆栈跟踪更新了这个问题。如果你看到,重试的时间很短。感觉就像它几乎不等待连接响应。在浏览器上完美运行。
  • 您可能永远无法修复它。例如,它可能对 Java 用户代理或 Java 支持的 TLS 协议版本过敏。
  • 因为你提到了 TLS 协议。他们的常见问题部分有一个 SSL 身份验证证书,我被允许下载。这是一个 .p7b 文件。我不知道该怎么办。但是你认为配置它可以帮助这种情况吗?
  • 另外,当我创建一个独立的简单 java 类并将此代码放入并将流作为字符串输出时,它似乎工作得很好。当我在我的 macbook 上的同一个 Tomcat7 上运行它时,它运行良好。但是如果我在我的 Ubuntu 机器上运行它,它就会失败。我认为它在我的 MacBook 上的 Tomcat 上运行这一事实将排除对 Java 用户代理点的过敏,对吧?但是 p7b 证书仍然可以提供线索。我不确定。
猜你喜欢
  • 1970-01-01
  • 2010-09-08
  • 2021-03-10
  • 2022-01-18
相关资源
最近更新 更多