If org.apache.httpcomponents:httpclient
/ org.apache.http.client.HttpClient
is on the classpath (which it often might be), by default RestTemplate
uses the HttpComponentsClientHttpRequestFactory
which uses a HttpClientBuilder
which by default uses a PoolingHttpClientConnectionManager
and initializes it with connTimeToLive = -1.
So Connections in the pool never "time out", but are checked before use if they are closed/stale.
In our case for some reason the connections in the pool became stale, without the check noticing it, resulting in Socket Timeout Exceptions when being used after they rest some time in the pool (maybe a proxy caused this without properly terminating the connection..?).
We decided to modify the default like this:
@Bean
public RestTemplateBuilder restTemplateBuilder(ObjectMapper objectMapper) {
return new RestTemplateBuilder()
.requestFactory(this::requestFactory);
}
private HttpComponentsClientHttpRequestFactory requestFactory() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS);
connectionManager.setDefaultMaxPerRoute(10);
connectionManager.setMaxTotal(30);
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setConnectionManager(connectionManager)
.build();
return new HttpComponentsClientHttpRequestFactory(httpClient);
}
so that after 30 seconds the connection is not reused anymore.
It also sets the maxPerRoute to 10 (instead of 5) and maxTotal to 30 (instead of 2*5 = 10).