sam
sam

Reputation: 173

Default keep-alive time for a HttpConnection when using Spring Rest Template

I am trying to know how long a HttpConnection is kept alive when inactive, before a new connection is created via Spring rest Template. I looked at default Connection Time-Out and Read Time-Out parameters, but I believe these are used in the context of connection time out when the connection is not established due to some failure etc.

What I am looking for is, how long a connection is kept alive if there is no activity (or) inactive, and how to configure this via Spring Rest Template (or) the underlying mechanism.

Upvotes: 16

Views: 32135

Answers (2)

icyerasor
icyerasor

Reputation: 5242

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).

Upvotes: 1

jny
jny

Reputation: 8057

By default RestTemplate uses SimpleClientHttpRequestFactory which in turn opens Java's HttpURLConnection which by default supports keep-alive under certain conditions. If you want more control over how connections are handled, you can create restTemplate with HttpComponentsClientHttpRequestFactory, which uses Apache HttpClient library, e.g:

@Bean
RestTemplate restTemplate(SimpleClientHttpRequestFactory factory) {
   return new RestTemplate(factory);
}

You can also see some discussions here:

How to Reuse HttpUrlConnection?

Persistent HttpURLConnection in Java

How to use RestTemplate efficiently in Multithreaded environment?

Upvotes: 11

Related Questions