Обмен темами против Direct Exchange в RabbitMQ - PullRequest
44 голосов
/ 14 марта 2012

У нас есть приложение, которое будет использовать 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")

Ответы [ 3 ]

34 голосов
/ 15 марта 2012

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

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

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

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

13 голосов
/ 25 апреля 2017

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

Тема обмена

QueueA-- binding key = India.Karnataka.*

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

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

Direct Exchange

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

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

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

6 голосов
/ 15 апреля 2015

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

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

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

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

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

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

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

...