Threadpool Deadlock: проектирование против или обнаружения

Я надеюсь, что это не слишком широко; У меня вопрос: "Как мне спроектировать сервис с несколькими пулами потоков, который не может заблокировать сам себя?".

У меня есть веб-сервис, который разветвляет до сотен потоков по запросу одного пользователя для агрегирования данных с малой задержкой. Существует множество ExecutorServices, обертывающих пулы с фиксированными потоками, разбросанных по всему моему сервису, и мне нужна помощь в поиске интересного способа, который может создать тупик.

У меня есть пул A который используется для хранения потоков, делающих сетевые запросы, и другого пула потоков B который используется для хранения их "владеющих" потоков; агрегационные биты бизнес-логики, которые могут распадаться на несколько запросов. Кроме того, темы в B иногда отправлять кусочки работы в пул потоков Bкогда агрегация может быть выполнена путем агрегирования 3 более простых субагрегаций.

Эта модель является проблемой. Давайте рассмотрим стиль запроса x представлен B что вызывает дополнительный запрос x' быть представленным B, Давайте также рассмотрим B фиксированный пул из 50 потоков. Когда 50 запросов типа x зайти одновременно, все темы B используются для обработки этих запросов. Все они представляют свои x1 в B, который сидит в очереди в ожидании потока. Затем вся обработка всех запросов заходит в тупик на 60 секунд, пока не истечет время ожидания, и x просит все возвратные исключения.

Вещи, которые я рассмотрел / попробовал:

  • Твик номера. Максимальное количество пользователей, которые могут подключиться, составляет 50, потоков в B 100. Предотвращает проблему, но кажется хаком, который сломается, когда другой разработчик подправит несвязанные числа через год, и никто не сможет понять, почему мы блокируемся один раз в неделю под нагрузкой. Я хочу решить это в дизайне.
  • B подчиняет раздутую работу B'новый пул потоков. Не работает, потому что этот разветвление может пройти несколько этапов (создать B'', B''',...?)
  • B не имеет максимальных потоков. Возможно, приемлемо, кажется опасным.
  • Другая модель (более обратная?), Где потоки не отправляют и не ждут той же единицы работы; скорее они отправляют работу и отправляют "обратный вызов" в пул "run-after". Таким образом, ничто не может ждать чего-то в своем собственном пуле. Есть ли прецедент, это хорошая идея?
  • Свернуть все пулы потоков вместе и удалить максимум?

1 ответ

Решение

Ваш "более обратный" ответ выглядит так, как будто он в основном решается за вас через API CompletionStage в Java 8 - отсутствие метода runAfterAllAsync означает, что вам, возможно, придется выполнить некоторую внешнюю работу, чтобы что-то произошло после того, как ваша группа 3 подзадачи, но именно здесь я бы начал искать. В этом уроке есть пример, который может помочь.

Другие вопросы по тегам