Какие best practices выбрать для архитектуры многопоточного java сервиса?
Делаю небольшое приложение на SpringBoot - агрегатор метрик. Одной из задач является получение определённых метрик из другого сервиса (сервис метрик) за указанный в настройках агрегатора лимит времени. То есть пользователь делает запрос в агрегатор, который в свою очередь должен, например, за 500 мс сделать как можно больше запросов в сервис метрик, отбросить все, которые не он не успел получить за указанное время и произвести над результатом определённую обработку и отдать пользователю. Изначально я планировал использовать executorService и Future объекты, чтобы проверять через метод get(), есть ли результат от запроса и далее агрегировать это всё по определённой логике. Непонятно сколько потоков генерить в executor при старте приложения, можно ли как-то это рассчитать? Вопрос какие проблемы в такой архитектуре, как сделать лучше?
Фраза 'сделать как можно больше запросов' содержит подводные камни, особенно когда у вас '500мс'.
Генерировать много потоков чтобы каждый лез в сеть и к кому то подключался - не лучшая идея (ну только что если запускать их заранее, а дальше этот пул висит и ждет команды), плюс на одни dns запросы вы можете потратить большую часть времени (кстати иногда это можно сделать так же заранее). Всегда есть возможность делать асинхронные запросы, ну почти всегда (бывает не вы делаете эти запросы, но лучше найти решение правильное).
p.s. это общие слова, не привязанные к используемым языкам и фреймворкам
Если запросы проходят быстро, то стоит начать с количества тредов, равного количеству ядер. Кодирование/декодирование запросов все равно будет лимитировано на ядра.
Если длительность запросов может быть разной, то стоит поглядеть на NIO -- там можно добиться сильно большей параллельности, но обработку все равно ограничить количеством ядер.