We are making a post call to an API, when we start calling this API after some time interval(most of the time in our case 10 mins, rarely we get if interval is 5 mins) we get Connection reset exception for the first attempt, then rest of the immediate calls works fine, but if there is interval of 10 minutes in calling this API and then call again, we get such exceptions in first call after that interval. We are using Java spring-boot Resttamplate to make API calls and using Apache httpclient-4.5.2
apache logs
"[read] I/O error: Read timed out"
Java logs
Connection reset; nested exception is java.net.SocketException: Connection reset
Resttamplate config
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
return restTemplate;
}
@Bean
public HttpComponentsClientHttpRequestFactory clientHttpRequestFactory() {
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setHttpClient(httpClient());
return clientHttpRequestFactory;
}
@Bean
public CloseableHttpClient httpClient() {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(180000)
.setConnectTimeout(180000)
.setSocketTimeout(180000).build();
return HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(poolingConnectionManager())
// .setKeepAliveStrategy(connectionKeepAliveStrategy())
.build();
}
@Bean
public PoolingHttpClientConnectionManager poolingConnectionManager() {
PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager();
poolingConnectionManager.setMaxTotal(50);
return poolingConnectionManager;
}
If we add set connectionKeepAliveStrategy in HttpClients.custom() as mentioned below, we won't get any such exception.
@Bean
public ConnectionKeepAliveStrategy connectionKeepAliveStrategy() {
return new ConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
HeaderElementIterator it = new BasicHeaderElementIterator
(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
String param = he.getName();
String value = he.getValue();
if (value != null && param.equalsIgnoreCase("timeout")) {
return Long.parseLong(value) * 1000;
}
}
return 20000;
}
};
}
Not sure why such exceptions gone with connectionKeepAliveStrategy. What is the role of it in this?. Thanks in advance.