Использование ForkJoinPool вместе с AsyncHttpClient - имеет ли смысл? - PullRequest
0 голосов
/ 27 марта 2020

Мои вопросы в некоторой степени связаны с этим вопросом о ForkJoinPool и операциях, ориентированных на ввод-вывод , но он несколько более общий (и вопрос, на который я ссылался, не получил однозначного ответа). Короче говоря - если я хочу отправлять много HTTP-запросов параллельно и уже использую асинхронный HTTP-клиент (например, AsyncHttpClient ), есть ли смысл отправлять запросы параллельно с использованием ForkJoinPool?

Изначально я думал, что это противоречит цели использования асинхронного HTTP-клиента, который уже позволяет отправлять запросы параллельно. Однако чтение этого связанного вопроса о ForkJoinPool , в котором упоминалось, что ForkJoinPool может повысить производительность даже «когда все задачи асин c и переданы в пул, а не разветвлены», заставило меня усомниться в том, насколько асинхронным операции работают в Java, и как они должны выполняться. Есть ли еще преимущество использования ForkJoinPool в моей ситуации, и если да, то как?

Я также прочитал этот вопрос о том, как отправлять HTTP-запросы в Parallel в Java, и там во всех ответах упоминается либо использование ExecutorService, либо AsyncHttpClient, но ни в одном ответе не упоминается и то и другое.

1 Ответ

1 голос
/ 27 марта 2020

Это ортогональные понятия, поэтому вы не видите их упомянутыми в одних и тех же ответах.

Целью AsyncHttpClient является (среди прочего) использование одиночного потока для всех сетевых коммуникаций (выполняется Netty через NIO Java неблокирующим асинхронным способом) вместо традиционной модели потока на запрос. Поверх единственного потока сетевого уровня библиотека имеет рабочие потоки, которые выполняют прикладной уровень асинхронной обработки, видимой для пользователей AsyncHttpClient, что означает, что она уже имеет (небольшой) внутренний пул потоков.

ForkJoinPool стремится максимизировать использование ЦП, имея много потоков (по умолчанию общий пул имеет CPU cores - 1, у тех, которые вы создаете, может быть больше / меньше) и путем кражи работы, так что потоки не простаивают, и это наиболее эффективно с небольшими рекурсивными задачами.

Ссылка обсуждает, что кража работы также эффективна с нерекурсивными задачами. Слово «асин c» отбросило вас туда, но оно просто относится к обычной задаче, которую вы отправляете в пул, и завершается асинхронно.

Так что вы можете либо сделать поток-на-запрос (например, Basi c I / O или «старый I / O») с пулом потоков, или , вы можете использовать однопоточный неблокирующий NIO (т.е. New I / O O) без пула потоков.

Объединять их не имеет смысла. Вы бы перешли с модели потока на запрос к неблокирующей модели для повышения производительности.

...