Reputation: 85
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.
Upvotes: 5
Views: 3345
Reputation: 7779
Check these two important points in:
Section 2.6 - Connection keep alive strategy:
Keep-Alive
header in the responseIf the Keep-Alive header is not present in the response, HttpClient assumes the connection can be kept alive indefinitely.
I am guessing there is one Keep-Alive
header in your api response with a value of 600 seconds.
keep-alive
strategy:However, many HTTP servers in general use are configured to drop persistent connections after a certain period of inactivity in order to conserve system resources, quite often without informing the client. In case the default strategy turns out to be too optimistic, one may want to provide a custom keep-alive strategy.
Upvotes: 4