Асинхронный HttpClient Apache не быстрый

Я новичок в http-клиенте Apache и пытаюсь получить код состояния с веб-сайта. Нашел следующий пример в учебнике Apache http.

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);
    }

}

Это действительно асинхронно или вызовы выполняются последовательно. Что нужно сделать, чтобы звонки были асинхронными и быстрыми.


person Harshit    schedule 12.02.2014    source источник


Ответы (2)


Поскольку запросы проходят по одному и тому же маршруту, необходимо будет внести следующие изменения.

CloseableHttpAsyncClient httpclient = HttpAsyncClients.custom()
            .setDefaultRequestConfig(requestConfig)
            .setMaxConnPerRoute(1000)
            .setMaxConnTotal(1000)
            .build();
person Harshit    schedule 13.02.2014
comment
почему 1000? есть ли способ переработать «httpclient»? - person Francisco Corrales Morales; 16.12.2014

Прежде всего: экземпляры CloseableHttpAsyncClient очень дороги. Пожалуйста, НЕ создавайте новый CloseableHttpAsyncClient для каждого запроса. Это похоже на создание нового процесса браузера для каждого клика по ссылке, совершенно расточительно и очень медленно. Настоятельно рекомендуется использовать один и тот же экземпляр CloseableHttpAsyncClient на протяжении всего срока службы логического компонента.

Практически во всех случаях блокирующий клиент, вероятно, будет значительно быстрее, чем неблокирующий (на основе NIO) (если количество одновременных запросов ниже, скажем, 1000). Если вы не создаете какой-либо прокси, вам может быть намного лучше обслуживать блокирующий HTTP-клиент, такой как Apache HttpClient.

person ok2c    schedule 12.02.2014
comment
На самом деле я хочу, чтобы все запросы выполнялись асинхронно, но это делает их последовательно. - person Harshit; 12.02.2014
comment
Естественно, если вы продолжите создавать новые экземпляры клиента для каждого запроса, вы будете выполнять только один запрос за раз. - person ok2c; 12.02.2014
comment
Я предполагаю, что экземпляр клиента был создан только один раз. Не могли бы вы провести меня через - person Harshit; 13.02.2014
comment
Я понял. Пришлось установить setMaxConnPerRoute(500), так как все запросы шли по одному и тому же маршруту. Спасибо бдв! - person Harshit; 13.02.2014