Подтвердить что ты не робот

Обмен темами и прямой обмен в RabbitMQ

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

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

Наличие единого обмена также похоже на то, что было бы немного легче поддерживать, но мне было интересно, есть ли какая-либо польза (если таковая имеется) в том, чтобы делать это одним способом над другим?

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

ExchangeA (type: direct)
-QueueA

ExchangeB (type: direct)
-QueueB

ExchangeC (type: direct)
-QueueC

Вариант 2, используя единый обмен темами:

Exchange (type: topic)
-QueueA  (receives messages from exchange with routing key of "TypeA")
-QueueB  (receives messages from exchange with routing key of "TypeB")
-QueueC  (receives messages from exchange with routing key of "TypeC")
4b9b3361

Ответ 1

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

Вариант 2 кажется более распространенным в реальном мире для решения этой проблемы маршрутизации (по крайней мере, в моем анекдотическом опыте), и это именно то, что существует для обмена Темами.

Единственная разница, с которой вы могли столкнуться, будет связана с скоростью маршрутизации. Я не уверен, что если маршрутизация Exchange (основанная всегда на точном совпадении строк) работает быстрее в RabbitMQ по сравнению с технологией ключа маршрутизации, используемой в разделе "Обмен тегами" (которая может включать в себя подстановочные знаки, такие как # и *). Моя догадка заключалась в том, что дискриминация Exchange будет быстрее, но вы можете поэкспериментировать для себя, чтобы узнать, или попытаться связаться с командой RabbitMQ, чтобы спросить их.

Наконец, если вы перейдете с опцией 1 в конечном итоге с большим количеством очередей, тогда у вас будет пропорциональное распространение Exchange. Это звучит как головная боль обслуживания. Если у вас будет только несколько очередей, это не будет проблемой.

Ответ 2

Действительно, подход 2 лучше, поскольку он дает вам гибкость в использовании одной очереди для нескольких ключей маршрутизации.

Тема Exchange

QueueA-- binding key = India.Karnataka.*

Вы можете направлять сообщение на тему обмена с помощью ключа маршрутизации, как India.Karnataka.bangalore, India.Karnataka.Mysore.

Все вышеперечисленные сообщения отправляются в QueueA.

Прямой обмен

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

QueueA-- binding key = Key1
QueueB-- binding Key = Key2
QueueC-- binding Key = Key3

Все сообщения key1 отправляются в QueueA.Key2 переходит в QueueB... Вы все равно можете поддерживать один прямой обмен.

Ответ 3

Для небольшого небольшого node с небольшой нагрузкой разница незначительна. Большинство людей идут по варианту два по указанным выше причинам.

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

Как это будет масштабироваться?
Нужно ли мне это масштабировать? Должен ли я добавить кластер с высокой степенью доступности в будущем? Будет ли моя маршрутизация изменяться...

Вариант 2 обеспечивает большую гибкость в большинстве случаев.

Он позволяет делать такие вещи, как прикрепление нового потребителя к Exchange со своей собственной очередью и легко захватывать любые подмножества или весь поток сообщений. (эти очереди могут быть на других узлах кластера или зеркалированы до n узлов, обеспечивающих переход на другой ресурс). Типичным примером использования будет запись всех сообщений с использованием 4-й очереди.

Если ваше узкое место находится на стороне обработки, вы также можете разделить ваши темы сообщений и выполнить некоторую приоритизацию, не изменив своих издателей. Пример: ToppicA.urgent, обработанный выделенным пользователем, в конечном итоге обработано в TextA.log.

Короткий ответ идет с опцией 2, если у вас нет особых требований к производительности. Если, например, вам нужно обработать, скажем, устойчивую скорость более 50 тыс. msg/s, вы можете подумать о опции 1 на выделенных узлах, но для обычных потоков вариант 2 будет легче масштабироваться и обслуживаться.

Ответ 4

Прямой обмен также поддерживает несколько маршрутов (https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-direct), так почему бы не использовать что-то вроде этого:

ExchangeA (type: direct)
-QueueA
-RoutingA

ExchangeB (type: direct)
-QueueB
-RoutingB

ExchangeC (type: direct)
-QueueC
-RoutingC