SSLException、SocketException:从 Apache HttpClient 重置连接

SSLException, SocketException : Connection reset from Apache HttpClient

我们正在使用 Apache HttpClient 库在 Spring 应用程序中调用 HTTP REST 端点。 我们现在经常收到“连接重置”错误,我们之前没有遇到任何问题,但错误现在开始出现,我们看到 100 个请求中有 1 到 5 个收到此错误。 我们用来创建 HttpClient 的代码如下所示:

RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectionRequestTimeout(connReqTimeoutInMillis)
                    .setConnectTimeout(connTimeoutInMillis)
                    .setSocketTimeout(socketTimeoutInMillis)
                    .build();

          CloseableHttpClient  client = HttpClientBuilder.create()
                    .setDefaultRequestConfig(requestConfig)
                    .setMaxConnPerRoute(numberOfConnections)
                    .setSSLSocketFactory(new SSLConnectionSocketFactory(SSLContext.getDefault(),
                            new String[]{"TLSv1.2"}, null,
                            ALLOW_ALL_HOSTNAME_VERIFIER)).build();

我们正在整个应用程序中使用此客户端对象。 所以我们进行的远程调用没有任何问题,因为我们在项目中从一个服务到另一个服务进行了一些调用,有时也有同样的问题。所有 HTTP 方法调用都会出现此问题。

确切错误:

有人可以帮忙吗,谢谢你的帮助!

经过大量分析,终于找到了解决这个问题的方法。

我们已经捕获了与服务器建立的所有连接的 TCP 转储,并与服务器团队共享了它。在分析 TCP 转储后,我们发现客户端中有一些连接打开的时间超过了服务器端的最大“keep-alive”值(在我们的例子中是 500 秒)。并且在我们这边打开的连接大约需要 600 到 800 秒,当再次使用相同的连接时,服务器会抛出连接重置。

我们使用的库是 Apache HttpClient,我们发现如果服务器没有在响应中传递“keep-alive”header,那么连接将在 client-side。一旦再次使用这个空闲连接,我们就会面临这个问题。

所以我们在 HTTP 客户端中添加了一个默认的 keep-alive 策略,并启动了一个调度程序来清除超过阈值的空闲连接,最终我们解决了这个问题。两种解决方案都可以在这里找到:

https://www.baeldung.com/httpclient-connection-management#keep-alive https://hc.apache.org/httpcomponents-client-4.5.x/current/tutorial/pdf/httpclient-tutorial.pdf