Как сбалансировать запросы паблишеров с RabbitMQ?

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

Производители работают с разной скоростью. Допустим, система A производит 10 запросов в секунду, а система B 1 запрос в секунду. Таким образом, если вы используете единственную очередь, вы обработаете 10 сообщений от A, а затем 1 сообщение от B.

Но что, если вы хотите сбалансировать нагрузку и обработать одно сообщение от A, затем одно сообщение от B и т. Д.? Использование нескольких очередей - не лучший вариант, потому что в этом случае мы не можем использовать привязку с подстановочными знаками.

Обновление:
Очередь на производителя кажется лучшим подходом. Производители не знают их скорость, которая постоянно меняется. Имея одну очередь для каждого потребителя, я могу подписаться на одну тему и получать сообщения от всех доступных издателей. Но имея очередь для каждого производителя, мне нужно самому кодировать логику:

  1. Получите все доступные очереди через плагин управления (AMQP не позволяет выводить список очередей).
  2. Фильтр по имени очереди.
  3. Реализуйте циклическую стратегию.
  4. Внедрите механизм уведомлений, чтобы подписаться на новых издателей, которые могут появиться в любой момент.
  5. Удалите ненужную очередь, когда издатель исчез и клиент прочитал все сообщения.

Что ж, это кажется довольно простым, но я думал, что брокер может предоставить все эти функции без какого-либо кодирования. В случае с одной очередью я просто создаю одну постоянную очередь, привязываю ее к обмену темами, а затем запускаю любое количество издателей, которые отправляют сообщения в тему. Этот вариант работает практически из коробки.


person Dmitry D    schedule 23.04.2015    source источник
comment
Непонятно, что вы имеете в виду, говоря, что нельзя использовать привязку с подстановочными знаками - пожалуйста, поясните свой вопрос, подробно объяснив, почему создание нескольких очередей невозможно.   -  person Gary Russell    schedule 23.04.2015


Ответы (2)


Я знаю, что опаздываю на вечеринку, но все же.

В терминах служебной шины Azure это называется секционированием и он основан на ключе раздела. Самое приятное то, что в Azure SB принимающий клиент не знает о секционировании, он просто подписывается на единственную очередь.

В RabbitMQ есть плагин X-Consistent-Hashing (rabbitmq_consistent_hash_exchange >) но, к сожалению, это не так удобно. Потребители должны быть явно настроены для использования из определенных очередей. Если у вас десять очередей, вам нужно настроить своих потребителей так, чтобы были охвачены все десять.

Еще два варианта:

  1. Случайный тип обмена
  2. Плагин Sharding

Имейте в виду, что с плагином Sharding, даже если он создает одну логическую очередь для использования, вам нужно иметь столько подписчиков, сколько существует виртуальных очередей, в противном случае некоторые очереди останутся неиспользованными.

person Gleb Teterin    schedule 28.01.2021

Вы можете использовать Priority Queue Support и связать приоритет в соответствии со скоростью производителя. С оговоркой, что приоритет следует устанавливать с осторожностью (например, если скорость потребителя ниже скорости системы B, потребитель будет потреблять только сообщения от B), а производители должны знать о своей скорости производства.

Другой вариант - создать 3 типа очередей в зависимости от скорости производства: HIGH, MEDIUM, LOW. Три очереди привязаны к обмену с ключом привязки, установленным в соответствии со скоростью производства. Это можно сделать с помощью.

Потребитель будет получать сообщения из этих 3 очередей, используя циклическую стратегию. С оговоркой, что производители должны знать о своей производственной скорости.

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

person Nicolas Labrot    schedule 23.04.2015