Использование нескольких пулов потоков и пула соединений - PullRequest
0 голосов
/ 13 февраля 2019

В настоящее время я использую 5 потоковых пулов и хочу найти оптимальный размер для этих пулов.Это какой-то предварительный анализ.Пулы разделены по использованию: для обработки команд (cmdPool), обработки транзакций инвентаризации (invPool), пула для транзакций базы данных (dbPool), а также пула для общих вещей, которые просто необходимо запустить асинхронно, таких как I / O (fastPool) и для запланированных задач(timerPool).У меня нет статистических данных, которые могли бы быть использованы для решения проблемы.

Для запроса к базе данных я использую HikariCP со значениями по умолчанию.Позже я попытаюсь изменить количество максимальных и минимальных незанятых соединений, чтобы найти оптимальную производительность.Но пока при использовании пула Hikari он всегда будет вызываться из одного из пулов, чтобы не влиять на основной поток.Обычный запрос к базе данных вызывается в dbPool, но только в том случае, если блок кода не является частью уже запускаемого объекта, переданного в один из пулов потоков.

Фактическая настройка выглядит так, как будто она работает прямо в приложении.Итак, мои вопросы:

1.) Как это повлияет на производительность и ресурсы, когда я решу прекратить использование cachedThreadPool и использовать пул с некоторыми минимальными бездействующими потоками, такими как timerPool, или я должен придерживаться кэшированного?

2.) Правильное решение - установить максимальный размер пула, чтобы предотвратить скачки, когда около 100 клиентов присоединятся за небольшой промежуток времени, и позволить им подождать некоторое время, пока выполнится другая задача.

3.) Есть ли лучшее решение, как управлять многими видами задач?

cmdPool = Executors.newFixedThreadPool(3);
invPool = Executors.newFixedThreadPool(2);
dbPool = Executors.newCachedThreadPool();
fastPool = Executors.newCachedThreadPool();
timerPool = new ScheduledThreadPoolExecutor(5);
timerPool.allowCoreThreadTimeOut(true);
timerPool.setKeepAliveTime(3, TimeUnit.MINUTES); 

Итак, во-первых, каждое действие зависит от того, сколько клиентов подключено, допустим значения, например, 5-25 клиентов.Пулы должны быть спроектированы так, чтобы поддерживать даже такие крайности, как 100 клиентов, и не создавать слишком много потоков за небольшой промежуток времени.

Ожидаемое использование может варьироваться и не одинаково каждую секунду, даже если это произойдет, никакие задачи не будут выполняться вообще.Ожидаемое использование cmdPool - 3-8 использования в секунду (легкие задачи).Для invPool использование почти такое же, как для cmdPool 2-6 использования в секунду (также облегченные задачи).Что касается dbPool, это более непредсказуемо, чем все остальные, но все же ожидаемое использование составляет от 5 до 20 использований в секунду (легкие и средние задачи), также зависит от того, насколько загружена сеть.Таймерные и быстрые пулы предназначены для выполнения любых задач и просто выполняют их, ожидается использование 20-50 применений в секунду.

Я ценю любые предложения, спасибо.

1 Ответ

0 голосов
/ 13 февраля 2019

Лучшее решение - адаптировать ваше приложение к ожидаемому трафику.Это можно сделать разными способами:

  • Разработать его с архитектурой микросервиса , оставив оркестратор для обработки пикового трафика
  • Разработать приложение, которое читает параметры размера пулов потоков на лету (из базы данных из файла, с сервера конфигурации ...), так что вы можете изменить значения при необходимости
  • Если вам нужно только настроить приложение, но вам не нужно менять значения на лету, поместите ваши конфигурации в файл (или базу данных).Проверьте различные конфигурации, чтобы найти наиболее адаптированные к вашим потребностям

Важно удалить код, подобный этому:

cmdPool = Executors.newFixedThreadPool(3);

и заменить его кодом, аналогичнымк этому

@Value("${cmdPoolSize}")
private int cmdPoolSize;

...

cmdPool = Executors.newFixedThreadPool(cmdPoolSize);

, где размер пула берется не из кода, а из внешней конфигурации .

Лучшим способом также является определениетип пула с параметрами:

@Value("${cmdPoolType}")
private String cmtPoolType;

@Value("${cmdPoolSize}")
private int cmdPoolSize;

...

if (cmdPoolType.equals("cached")) {
  cmdPool = Executors.newCachedThreadPool();
} else if (cmdPoolType.equals("fixed")) {
  cmdPool = Executors.newFixedThreadPool(cmdPoolSize);  
}

Где вы выбираете разумный тип доступных пулов.

В этом последнем случае вы также можете использовать файл конфигурации Spring и изменить его перед запускомприменение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...