Apache async HttpClient not fast
Solution 1
As the requests are going through the same route following changes will have to be made.
CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
.setDefaultRequestConfig(requestConfig)
.setMaxConnPerRoute(1000)
.setMaxConnTotal(1000)
.build();
Solution 2
First and foremost: CloseableHttpAsyncClient
instances are very expensive. Please do NOT create a new CloseableHttpAsyncClient
for each and every request. It is like creating a new browser process for each link click, is completely wasteful and is very slow. It is strongly recommended to use the same CloseableHttpAsyncClient
instance for the entire lifespan of a logical component.
Pretty much in all cases a blocking client is likely to be considerably faster than a non-blocking (NIO based) one (as long as the number of concurrent requests is below, say, 1000). Unless you are building a proxy of some sort you might be much better served by a blocking HTTP client such as Apache HttpClient.
Comments
-
Harshit almost 2 years
I am pretty new to Apache http client and am trying to get status code from a website. Found the following example on Apache http tutorial.
import java.util.concurrent.CountDownLatch; import org.apache.http.HttpResponse; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.concurrent.FutureCallback; import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; import org.apache.http.impl.nio.client.HttpAsyncClients; public class Abc { static long d2; public static void main(final String[] args) throws Exception { d2=System.currentTimeMillis(); RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(3000) .setConnectTimeout(3000).build(); CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom() .setDefaultRequestConfig(requestConfig) .build(); try { httpclient.start(); final HttpGet[] requests = new HttpGet[] { new HttpGet("http://192.168.26.175:8080/examples/eye/abc10000.jsp") }; final CountDownLatch latch = new CountDownLatch(1); for (int v=0;v<1000;v++) { httpclient.execute(requests[0], new FutureCallback<HttpResponse>() { public void completed(final HttpResponse response) { latch.countDown(); System.out.println(requests[0].getRequestLine() + "->" + response.getStatusLine()); } public void failed(final Exception ex) { latch.countDown(); System.out.println(requests[0].getRequestLine() + "->" + ex); } public void cancelled() { latch.countDown(); System.out.println(requests[0].getRequestLine() + " cancelled"); } }); } latch.await(); System.out.println("Shutting down"); } finally { httpclient.close(); } System.out.println("Done"); long d1=System.currentTimeMillis(); System.out.println(d1-d2); } }
Is it really asynchronous or are the calls made serially. What has to be done to make calls asynchronous and faster.
-
Harshit over 10 yearsI actually want all the requests to be done asynchronous but what it is doing is that making them serially.
-
ok2c over 10 yearsNaturally, if you keep on creating new client instances for each request, you will be executing only one request at a time
-
Harshit over 10 yearsI guess the client instance has been made only once. Could you please guide me through
-
Harshit over 10 yearsI figured it out. Had to set
setMaxConnPerRoute(500)
as all the requests went through the same route. Thanks bdw! -
Francisco Corrales Morales over 9 yearswhy 1000 ? is there a way to recycle the 'httpclient' ?