Reputation: 13051
I recently switched from java.net
to org.apache.http.client
, I have setup a ClosableHttpClient
with the HttpClientBuilder
. As connection manager I am using the BasicHttpClientConnectionManager
.
Now I have the problem that very often when I create some HTTP request I get a timeout exception. It seems that the connection manager is keeping connections open to reuse them but if the system is idle for a few minutes then this connection will timeout and when I make the next request the first thing I get is a timeout. Repeating the same request one more time then usually works without any problem.
Is there a way to configure the BasicHttpClientConnectionManager
in order to not reuse its connections and create a new connection each time?
Upvotes: 1
Views: 2639
Reputation: 27538
There several ways of dealing with the problem
Evict idle connections once no longer needed. The code below effectively disables connection persistence by closing out persistent connections after each HTTP exchange.
BasicHttpClientConnectionManager cm = new BasicHttpClientConnectionManager();
CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(cm).build();
...
try (CloseableHttpResponse response = httpclient.execute(new HttpGet("/"))) {
System.out.println(response.getStatusLine());
EntityUtils.consume(response.getEntity());
}
cm.closeIdleConnections(0, TimeUnit.MILLISECONDS);
Limit connection keep-alive time to something relatively small-ish
BasicHttpClientConnectionManager cm = new BasicHttpClientConnectionManager();
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm)
.setKeepAliveStrategy((response, context) -> 1000)
.build();
try (CloseableHttpResponse response = httpclient.execute(new HttpGet("/"))) {
System.out.println(response.getStatusLine());
EntityUtils.consume(response.getEntity());
}
(Recommended) Use pooling connection manager and set connection total time to live to a finite value. There are no benefits to using the basic connection manager compared to the pooling one unless your code is expected to run in an EJB container.
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionTimeToLive(5, TimeUnit.SECONDS)
.build();
try (CloseableHttpResponse response = httpclient.execute(new HttpGet("/"))) {
System.out.println(response.getStatusLine());
EntityUtils.consume(response.getEntity());
}
Upvotes: 1