Как связать frontend c backend-ом, backend с внешним медленным сервисом для возможности параллельной обработки множества запросов?
Добрый день!
Разрабатываю сервис, работающий с сервисом пополнения карт. Задача моего сервиса обеспечить удобства работы персонала с внешним сервисом пополнения - авторизацию персонала, логирование всех операций, просмотр истории операций и т.п.
Но главная задача это возможность группового пополнения, когда можно например задать сотню карточек, указать сумму и все карточки будут пополнены.
Внешнему сервису нужно давать по одному запросу, он не имеет возможности группового пополнения.
Фронтенд (Javascript + JQuery) с бекендом (Java) в данный момент связан через websocket-ы.
В данный момент я реализовал это таким образом что фронтенд поочередно из списка карт кидает мне номер карты и сумму и ждет от бекенда ответа (с обработкой таймаутов и т.п.). Бекенд в свою очередь формирует полноценный запрос, отправляет на внешний сервис и ждет ответа. После получения ответа он отправляет ответ по открытому websocket-у назад на фронтенд. Тот в свою очередь уведомляет пользователя об успешности или неуспешности операции и переходит к следующей карте.
Основная проблема - внешний сервис долго обрабатывает запрос (до 10-и секунд) и если карт много, то пополнения при таком подходе затянется надолго.
Хотелось бы все это делать параллельно.
Есть мысли как это можно сделать на бекенде(с фронтенда получать весь список карт):
1 - добавить многопоточность. Забросить список карт в виде отдельных сообщений в очередь и в пуле потоков выгребать карты из очереди, делать внешние запросы (блокирующие потоки), после получения ответов от сервера класть ответы в другую очередь, эту результирующую очередь разбирать потом отдельным процессом, который в свою очередь будет логировать результаты операций и класть результаты в базу.
Вот только не знаю как лучше сделать это с точки зрения фронтенда. Хотелось бы видеть текущий процесс, происходящий на сервере так сказать "онлайн". Как вариант, открыть websocket и кидать туда с бекенда сообщения о результатах обработки каждой карточки.
2 - перейти к микросервисной архитектуре. Вынести процессы общения с внешним сервисом в виде отдельного сервиса и просто запускать их N-е количество. Фронтенд перевести на Angular и делать с фронтенда полноценные REST запросы к этим микросервисам.
Но вопрос в том, что, насколько я понимаю, фронтенд однопоточный и потому смогу ли я сделать много параллельных REST запросов к микросервисам?
Подскажите пожалуйста какой путь более предпочтительный?
Буду благодарен за любую критику и ссылки на полезные материалы!
Вы намешали все в кучу. Разберем по полочкам:
1. вы не сказали что у вас за фронтэнд. Обычный JS, полагаю?
2. Никакой фронтэнд не однопоточный, если только вы сами так не сделали
3. Микросервисная архитектура это хорошо, делайте, но к вашей задаче не относится никак
4. Для распараллеливания на бэкэнде для вашей задачи познакомьтесь с Message Broker: RabbitMQ или Kafka, например
Иван, спасибо за ответ!
1 - да, сейчас у меня просто JS на фронтенде.
2 - ну фактически он получился однопоточный, потому что я отправил ответ и не шлю следующий пока не получил ответ по предыдущему. В данный момент у меня один websocket используется, т.е. я открыл соединение, передал по нему что-то, не закрываю пока не получил ответ или оно само не закрылось. Я так понимаю, можно просто открывать несколько соединений параллельно. Правильно понимаю? Или как лучше сделать?
3 - я имел ввиду использование микросервисов для того чтобы получить подобие распределенной системы, хотя наверное в данном случае оно явно лишнее, т.к. один сервис и так сможет обрабатывать множество параллельно приходящих запросов (если распараллеливание сделать до него, например на фронтенде).
4 - Использование уже готовых брокеров сообщений лучше с точки зрения того чтобы не городить самописные очереди сообщений (со всеми вытекающими из самописного решения багами)?
Павел,
2. вы вебсокеты использовали не по назначению. Тут Rest более чем достаточен
3. вы совсем не правильно понимаете и явно не читали спецификации протоколов с которыми работаете. что Websocket, что http. Кроме того вам надо прочитать про масштабирование систем (в первую очередь добавление воркеров и тут вам RabbitMQ в помощь для понимания)
4. да, эти продукты делают свою работу лучше чем все то что вы сами сделаете за много лет
Да, Вы абсолютно правы.
2 - Я изначально планировал открыть вебсокет и с сервера кидать туда нотификации, но потом как-то в итоге это переросло фактически в использование просто 1 запрос/1 ответ. Потому Rest будет более правильным вариантом.
3 - Спасибо, почитаю про RabbitMQ и про масштабирование систем.
4 - согласен.