Messaging / RabbitMQ: обратная связь с производителем после завершения обработки потребителем - PullRequest
0 голосов
/ 05 февраля 2019

Я работаю в службе, которая обрабатывает некоторые входные данные (скажем, параметры для расчета цены) от имени пользователя и генерирует выходные данные (скажем, рассчитанная цена).Расчет может занять до 20 секунд.

Текущая ситуация

Сейчас у меня есть вычисления, доступные через HTTP-вызов.Например,

curl -X POST \
    -H "Content-Type: application/json" \
    --data '{"param1": "value"}' \
    https://api.my-service.com/v1/calculate

Я получаю результат, подобный

{ "price": 55.00 }

Проблема

Мы сталкиваемся с проблемами классической масштабируемости.Когда мы достигаем дневного пика и имеем несколько сотен одновременных запросов, время отклика резко возрастает.Поэтому я хотел бы реализовать очередь с запросами на расчет цены.

Возможные решения

Я считаю, что использование очереди сообщений - наш путь вперед.Я не хочу вдаваться в конкретные технологии здесь, но мы экспериментируем с RabbitMQ прямо сейчас.

В общем, архитектура будет выглядеть так:

 client 
    ▲
    | HTTP
    ▼
 ------------------                          -------------------
| Producer (service|                        | Consumer (service |
| requesting price | --> RabbitMQ Queue --> | calculating price)|
| calculation)     |      |  |  |  |  |     |                   |
 ------------------                          -------------------

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

Вариант 1: оставить запрос HTTP открытым до тех пор, пока потребитель не выполнит

Мы можем построить вторую очередь, в которой потребитель может публиковатьсообщение после расчета.Производитель получит это сообщение и отобразит результаты для пользователя:

 client 
    ▲
    | HTTP
    ▼
 ------------------                          -------------------
| Producer (service|                        | Consumer (service |
| requesting price | --> RabbitMQ Queue --> | calculating price)|
| calculation)     |      |  |  |  |  |     |                   |
 ------------------                          -------------------
                     <-- Feedback Queue --  

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

Вариант 2: опрос результатов

Второй вариант: мы можем отменить запрос от клиента к производителюи закройте HTTP-соединение в этой точке.Затем клиент может регулярно опрашивать обновления от производителя, чтобы узнать, завершилось ли вычисление:

 client          
    | HTTP:       ▲
    | calculate   | HTTP: Poll until
    | price!      | calculation has
    ▼             | finished
 ------------------                          -------------------
| Producer (service|                        | Consumer (service |
| requesting price | --> RabbitMQ Queue --> | calculating price)|
| calculation)     |      |  |  |  |  |     |                   |
 ------------------                          -------------------
                     <-- Feedback Queue --  

Мне нравится этот подход, поскольку он минимизирует накладные расходы ввода-вывода и устраняет любые проблемы тайм-аута HTTP.Но кажется, что это лишь нерешительная реализация шаблона обмена сообщениями.

Вопрос

Я уверен, что должны быть другие, кто реализовал подобный вариант использования и внедрил любое решение.Я ищу ваши уроки / ошибки и ваши рекомендации.

...