Как организовать много параллельных запросов к разным серверам/API?
Здравствуйте, уважаемые коллеги.
Имеется сайт - интернет-магазин с возможностью поиска товаров по каталогам поставщиков и заказа через наш сайт. Каталогов, естественно дофига и больше, каждый со своим API, который возвращает ответ в своем формате.
Что хотелось бы получить: Поиск примерно как на скайсканере, когда на один запрос приходит несколько ответов от различных поставщиков. Т.е. что-то типа специализированного поисковика, который ищет определенный товар и его наличие в текущий момент.
На данный момент это работает так:
1. Делается запрос на бэк
2. Curl'ом по очереди делается запрос к одному из поставщиков по списку
3. Данные ото всех поставщиков сортируются, фильтруются и выдаются в нужном виде.
Проблемы:
1. Общее быстродействие не очень
2. Если один API начинает лагать, то только остается дожидаться таймаута и только потом переходить к следующему.
Как организовать много параллельных запросов к разным серверам/API? Кэширование, в данном случае, не помогает, т.к. нужно проверять наличие редких товаров у конкретного поставщика
На ум приходит 2 идеи:
1. Организовать n количество запросов с фронта к моему бэку с указанием поставщика, соответственно на бэке запуститься n*кол-во ищущих посетителей запросов. Помимо некой костыльности этого решения, возникает вопрос, не сожрет ли это все память?
2. Как-то переписать код с phtreads, чтобы это все выполнялось параллельно, но возникает вопрос, как сделать так, чтобы результаты возвращались на фронт/обновлялись с получением ответа от каждого источника?
В маленьком масштабе можно использовать параллельные curl запросы через curl_multi_init() – их выполнение займёт сколько длится самый тормозной из запросов.
В бОльшем масштабе нужно поднимать очередь задач, параллельные машины/процессы «рабочие».
RabbitMQ на беке и long-polling/WebSocket на клиенте.
Вкратце, схема такая: клиент шлет запрос на поиск на бэкенд (в некий диспетчер задач), подписывается на получение результатов (тут используются WebSocket'ы) и собственно ждет их. Диспетчер раскидывает задачи в очередь (RabbitMQ) и умирает. Обработчики (можно горизонтально смасштабировать на n-машин) делают запросы к сторонним API (т.е. полезную работу), получают результат и отдают клиенту.
Кеширование и остальные плюшки добавляются по вкусу.