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 方法调用都会出现此问题。
确切错误:
- javax.net.ssl.SSLException:java.net.SocketException:连接重置
- 已抑制:java.net.SocketException:管道损坏(写入失败)
有人可以帮忙吗,谢谢你的帮助!
经过大量分析,终于找到了解决这个问题的方法。
我们已经捕获了与服务器建立的所有连接的 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
我们正在使用 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 方法调用都会出现此问题。
确切错误:
- javax.net.ssl.SSLException:java.net.SocketException:连接重置
- 已抑制:java.net.SocketException:管道损坏(写入失败)
有人可以帮忙吗,谢谢你的帮助!
经过大量分析,终于找到了解决这个问题的方法。
我们已经捕获了与服务器建立的所有连接的 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