Как работает HttpAsyncClient 4?

В предыдущих версиях HttpClient целевой хост устанавливался в самом клиенте. В последней версии (для HttpAsyncClient это 4.1.1) хост настраивается на HttpRequest (HttpGet, HttpPost и т. д.) каждый раз, когда я делаю запрос.

Я хочу использовать постоянное соединение, поэтому использую HttpAsyncClient. Я создаю и использую его следующим образом:

CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
client.start();
List<Future<HttpResponse>> responses = new ArrayList<>();
for (int i = 0; i < 10; i++)
{
    HttpGet get = new HttpGet("https://google.com/");
    responses.add(client.execute(get, null));
}
for (Future<HttpResponse> response : responses) {
    response.get(); //wait for the response
}

Как я тестировал, работает быстрее обычного HttpClient (если делать все запросы, а потом ждать всех ответов).

Но я не могу до конца понять, как это работает внутри. Сколько соединений с https://google.com/ установлено? Что произойдет, если я использую client для одного хоста, а затем для другого? (как я проверял, ответы могут приходить в любом порядке, поэтому я полагаю, что есть как минимум 2 параллельных соединения). В чем разница между HttpAsyncClients.createDefault() и HttpAsyncClients.createPipelining() ?

Спасибо!


comment
Ваш вопрос довольно сложен, то есть слишком абстрактен и, возможно, относится к другому форуму. Я не искал никаких спецификаций, но предполагаю, что HttpAsyncClient создает поток, потому что класс Future является частью пакета параллелизма. Поэтому ваша программа создает десять фоновых потоков, которые работают независимо на различных ядрах вашего компьютера. Мой самый простой ноутбук имеет четыре ядра, поэтому я получаю в четыре раза больше производительности, когда запускаю несколько потоков. Если вы используете обычный HttpClient, то вы выполняете 10 последовательных запросов, ожидая завершения каждого до начала следующего.   -  person K.Nicholas    schedule 03.01.2016
comment
Future можно использовать в HttpAsyncClient из-за асинхронной работы с HTTP (метод javadoc at execute() это подтверждает). Так что нет, речь идет не только о потоках (хотя я согласен - наверняка внутри HttpAsyncClient создаются какие-то потоки (демоны).   -  person coolguy    schedule 03.01.2016
comment
HttpAsyncClient использует небольшое количество потоков диспетчеризации ввода-вывода (равное количеству ядер ЦП по умолчанию) для обработки и обработки всех сообщений.   -  person ok2c    schedule 04.01.2016


Ответы (1)


По умолчанию HttpAsyncClient разрешает только два одновременных подключения к одному и тому же узлу в соответствии со спецификацией RFC 2616. Этот предел не имеет ничего общего с количеством потоков диспетчеризации ввода-вывода, используемых внутри реактора ввода-вывода.

Приведенный выше код создаст не более двух исходящих соединений.

Конвейерная обработка HTTP-сообщений не имеет ничего общего с постоянным соединением как таковым, хотя выполнение конвейерного запроса подразумевает использование постоянных соединений.

Конвейерная обработка HTTP связана с последовательностью сообщений. HttpAsyncClient в конвейерном режиме может отправлять несколько запросов, не дожидаясь каждого ответа.

Режим по умолчанию:

C -> request1 -> S
C <- response1 <- S
C -> request2 -> S
C <- response2 <- S

Конвейерный режим:

C -> request1 -> S
C -> request2 -> S
C <- response1 <- S
C <- response2 <- S
person ok2c    schedule 04.01.2016
comment
Теперь все ясно, спасибо. Может быть, вы сможете ответить на мой еще один вопрос о HttpAsyncClient? stackoverflow.com/questions/34576416 Есть ли разница в HTTP-запросах, созданных по умолчанию, или в конвейерной обработке HttpAsyncClient? Для меня это очень важно, я даже завтра начну баунти. - person coolguy; 04.01.2016
comment
Не используйте конвейерную обработку сообщений, если у вас нет особой потребности в ней, например, мобильное соединение с большой задержкой. - person ok2c; 04.01.2016
comment
У меня есть веская причина его использовать — меня не особо волнуют ответы, и мне нужно повысить производительность сети (я имею в виду, мне нужно быстрее отправлять запросы). - person coolguy; 04.01.2016
comment
если у вас нет соединения с высокой задержкой, конвейерная обработка вряд ли повысит производительность, но, скорее всего, вызовет всевозможные проблемы с совместимостью. - person ok2c; 04.01.2016