#java #asynchronous #threadpoolexecutor
#java #асинхронный #threadpoolexecutor
Вопрос:
Я работаю с клиентским приложением, которому необходимо запрашивать данные из Rest API. Многие из этих запросов независимы, поэтому их можно вызывать асинхронно. Для этого я использую ThreadPoolExecutor, и я видел, что его можно настроить с помощью нескольких параметров:
- corePoolSize
- maxPoolSize
- Емкость очереди
Я прочитал эту статью и понял следующее:
- corePoolSize — это значение, ниже которого исполнитель добавляет новый поток, а не ставит его в очередь
- maxPoolSize — это значение, выше которого исполнитель помещает запрос в очередь
- Если количество фактических потоков находится между corePoolSize и maxPoolSize, запрос ставится в очередь.
Но у меня есть несколько вопросов:
- Я тестировал, и чем выше corePoolSize, тем лучшие результаты я получаю. Насколько высоким должен быть corePoolSize в производственной среде с большим количеством клиентов, обращающихся к этому Rest API (возможно, миллионы в день)?
- Как я должен действовать, чтобы получить «оптимальные» параметры? Только путем тестирования?
- Какие проблемы могут вызывать высокие / низкие значения (каждого параметра)?
Заранее благодарю вас
Обновить
Мои текущие значения:
- corePoolSize = 5
- maxPoolSize = 20
- Вместимость очереди = 100
Комментарии:
1. Ваше понимание неверно (и я не смог найти в связанной статье ничего, что могло бы привести к этому). Обратите внимание, что из того, что вы говорите, maxPoolSize является избыточным, поскольку вы ставите запросы в очередь как тогда, когда количество потоков выше, так И ниже его.
2. Примечание: размер пула не увеличивается, если задача может быть добавлена в очередь. Вы можете обнаружить, что наличие большего количества потоков помогает, даже если вы не заполняете свою очередь.
Ответ №1:
- это
corePoolSize
количество потоков, которые нужно сохранить в пуле, даже если они простаивают, если не задан параметр {@code allowCoreThreadTimeOut} maximumPoolSize
это максимальное количество потоков, разрешенных в пуле
corePoolSize — это количество потоков, которые вы хотите поддерживать в ожидании вечно, даже если их никто не запрашивает. Это maximumPoolSize
максимальное количество потоков и, следовательно, количество одновременных запросов к вашему Rest API, которые вы запустите.
- Сколько запросов в секунду у вас есть? (среднее / максимальное в секунду).
- Сколько времени занимает один запрос?
- Как долго длится максимально допустимое время ожидания для пользователя?
corePoolSize >= requests per second * seconds per request
maximumPoolSize >= maximum requests per second * seconds per request
queueCapacity <= maximumPoolSize * maxWaitTime / timePerRequest
(Вы должны следить за этим, чтобы знать, когда вам придется действовать.)
Вы должны иметь в виду, что Rest API или ваше собственное приложение / сервер / пропускная способность могут налагать некоторые ограничения на количество одновременных подключений и что многие одновременные запросы могут увеличить время на запрос.
Я бы предпочел сохранить corePoolSize
низкий, keepAliveTime
довольно высокий.
Вы должны иметь в виду, что каждый поток добавляет довольно много накладных расходов только для параллельных HTTP-запросов, должен быть вариант NIO, который делает это без большого количества потоков. Может быть, вы могли бы попробовать Apache MINA.
Комментарии:
1. Большое вам спасибо за ваш ответ