Pav*_*hov 3 java socket-timeout-exception apache-httpcomponents apache-httpclient-4.x
我创建了一个 Apache HTTP 客户端
CloseableHttpClient client = HttpClients.custom()
.setMaxConnPerRoute(25)
.setMaxConnTotal(50)
.setDefaultRequestConfig(RequestConfig.custom()
.setConnectionRequestTimeout(20_000)
.build())
.build();
Run Code Online (Sandbox Code Playgroud)
我将它用作单例。我有这种发送请求的方法:
public RestResponse sendPost(String serverUrl, String body) throws RestException {
try {
HttpPost httpPost = new HttpPost(serverUrl);
httpPost.setEntity(new StringEntity(body));
try (CloseableHttpResponse response = client.execute(httpPost)) {
RestResponse restResponse = new RestResponse();
restResponse.setCode(response.getStatusLine().getStatusCode());
restResponse.setBody(EntityUtils.toString(response.getEntity()));
return restResponse;
}
} catch (Exception e) {
throw new RestException(e);
}
}
Run Code Online (Sandbox Code Playgroud)
效果很好。但是闲置一段时间(5-6 分钟)后,如果我发送请求,我会得到"java.net.SocketException: Connection reset"
我有 2 个问题
我怎样才能找到这个时间开始的地方?这些参数对我不起作用
.setSocketTimeout(25_000)
.setConnectTimeout(26_000)
Run Code Online (Sandbox Code Playgroud)
解决这个问题的最佳方法是什么?(我的意思是在每个请求之后或之前重试请求或更改超时或重新连接)
这是经典(阻塞)I/O 的一般限制:阻塞连接在空闲(未参与 I/O 操作)时无法对任何 I/O 事件做出反应。同样,超时设置对空闲连接没有影响。
人们可以采用多种防御措施来最大程度地减少持久连接重置的可能性:
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setValidateAfterInactivity(1000);
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm)
.build();
Run Code Online (Sandbox Code Playgroud)
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setValidateAfterInactivity(1000);
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm)
.evictExpiredConnections()
.evictIdleConnections(5L, TimeUnit.SECONDS)
.build();
Run Code Online (Sandbox Code Playgroud)
HttpRequestRetryHandler当需要更多控制时,人们可能希望使用自定义实现而不是默认实现。 PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setValidateAfterInactivity(1000);
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm)
.setRetryHandler(DefaultHttpRequestRetryHandler.INSTANCE)
.build();
Run Code Online (Sandbox Code Playgroud)
evictIdleConnections方法时自动为您所做的事情,但需要额外的监视线程。 cm.closeIdleConnections(0, TimeUnit.MICROSECONDS);
Run Code Online (Sandbox Code Playgroud)