Производительность MQ vs REST в многопоточности - PullRequest
0 голосов
/ 08 июля 2019

В настоящее время у меня есть механизм обмена сообщениями, который обрабатывает тысячи запросов в секунду, производительность плохая, потому что текущая реализация использует службу REST, которая является блокирующей операцией, поэтому в итоге заканчиваются потоки из пула потоков, так как Потребляя службу REST поверх HTTP, я понимаю, что у меня нет возможности запустить запрос «запусти и забудь», по крайней мере, мне нужно дождаться ответа HTTP, даже если используется Future, это будет работать в другом потоке, поэтому, даже если основной поток не заблокирован, он в любом случае приведет к истощению пула потоков, поэтому мой вопрос: если бы у меня было такое большое количество параллелизма, было бы лучше отправить это MQ вместо? таким образом, это больше не будет блокирующей операцией, верно? В настоящее время приложение работает на платформе Akka.

1 Ответ

0 голосов
/ 10 июля 2019

Итак, исходные данные следующие:

  • ваша программа выдает тысячи запросов в секунду к службе REST,
  • POST-запрос занимает больше 1 секунды,
  • заканчивается поток из пула потоков.

Первое, что вы должны проверить: сколько одновременных запросов может выполнить служба REST? Может ли быть так, что он не может обрабатывать тысячи запросов в секунду, а большая синхронизация одного запроса является результатом перегрузки службы? Затем вы должны установить механизм ограничения скорости ваших запросов. На самом деле, устанавливать такой предел - хорошая идея при любых обстоятельствах.

Во-вторых, вы должны решить, может ли такая скорость доступа быть достигнута с помощью синхронного или асинхронного ввода-вывода. Синхронный ввод-вывод проще и быстрее, но требует большего расхода памяти для потоков. Грубая оценка выглядит следующим образом:

  • менее 100 одновременных запросов: используйте синхронизацию
  • более 10000 одновременных запросов: используйте async
  • между: в любом случае

Если вы решили использовать синхронный ввод-вывод, то самый простой и естественный способ установить ограничение частоты запросов - это использование семафора: поток, желающий выполнить следующие запросы, получает объект семафора, а после получения ответа освобождает его , Оставьте количество потоков в пуле потоков равным пределу запроса.

Если вы решили использовать синхронный ввод-вывод, то универсального механизма для установки такого ограничения не существует, поскольку асинхронные семафоры обычно недоступны для разработчика. Если ваша асинхронная библиотека ввода / вывода имеет реактивный интерфейс, используйте ее (асинхронные семафоры являются частью механизма противодавления). Если нет, вы можете создать такой механизм из следующих компонентов:

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

Этот механизм использует один поток для всех асинхронных запросов, поэтому он занимает не так много памяти и работает достаточно быстро. Однако, если вам нужно, чтобы он работал быстрее, просто увеличьте количество потоков.

...