Есть задумка некой системы, которая складирует и запрашивает некие данные в JSON-формате. Выбран фреймворк -spring и среда исполнения - Apache Tomcat. База данных - PostgreSQL.
Некие клиенты периодически выполняют Rest запросы (POST для отправки сообщений и GET для получения данных). Когда сообщение приходит на tomcat, оно кладется в RabbitMQ для сохранности, когда у приклада на tomcat будет время - он забирет сообщение и обрабатывает его, тут все понятно, но вот когда клиент спрашивает некие данные, то я не знаю никакого способа очень быстро достать пачку данных из базы и отдать клиенту кроме как с помошью org.springframework.web.context.request.async.DeferredResult . Основная идея в том, что спринг отправляет на клиент 202 ACCEPTED, лезет в базу и достает пачку данных, а клиент выждав тайм-аут и сделав запрос получает всю пачку сообщений уже из памяти.
Исходя из вышеописанного есть вопросы:
1) Как снизить нагрузку на сам tomcat? DeferredResult - это хорошо, но что еще можно сделать?
Сюда же - DeferredResult создает поток (как я предполагаю), как защититься от того, что при слишком большом кол-ве запросов у меня просто умрет все от такого кол-ва потоков?
2) Если производительности одного tomcat не хватит, то что можно сделать? Поставить Nginx (или HProxy) и разруливать запросы на несколько физических машин на которых стоят томкаты, а базу реплицировать?
Обычно используют пул потоков фисированного размера (или с ограничением на макс кол-во)
Можно масштабировать горизонтально, но обычно сначала вводят кеширование на разных уровнях приложения. Можно разделять данные на горячие/холодные и хранить первые целиком в оперативке. Все зависит от объемов данных и вариативности запросов к ним