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

2

16

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.

Gelatinate answered 3/2, 2016 at 18:37 Comment(2)
Are you planning to keep http connections open between calls?Liverish
I am trying to understand what the default behavior is, how long the connection is available while it is inactiveGelatinate
L
11

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?

Liverish answered 3/2, 2016 at 20:38 Comment(3)
Thanks for the answer it helps me get going, one last question I am using the plain RestTemplate with SimpleClientHttpRequestFactory, basically the first request takes around 5 seconds in connecting to another REST Service via(RestTemplate), I see that java.net.UrlConnection.connect() is taking, but subsequent calls are fast. The delay happens again if the server is idle for a minute, IS this the default behavior? Does pooling connections eliminates that delay, when the server is idle?Gelatinate
Usually it takes a lot less than 5 seconds to connect. There could be a network problem or the problem with the destination rest service.Liverish
I was searching how to reuse a session cookie upon success logon and with HttpComponentsClientHttpRequestFactory it works great (no need to add the cookie for each new request)Promethean
C
1

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

Counterattraction answered 2/1, 2023 at 16:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.