Как сделать так, чтобы Ребус хорошо играл с настраиваемым обменом темами в RabbitMQ?

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

Насколько я могу судить, право собственности на сообщение представлено просто строкой. Используя транспорт MSMQ, эта строка указывает на очередь, в которую доставляется сообщение. В RabbitMQ строка используется как тема для сообщения, которое затем доставляется в общий обмен с именем "Rebus". Ребус - хороший парень, поэтому он также создает очередь на сервере RabbitMQ, используя то же имя, и делает привязку от темы к очереди в рамках обмена Rebus.

У меня такой вопрос: возможно ли, чтобы Ребус не создавал очереди и привязки, но по-прежнему доставлял сообщения в обмен с соответствующей темой, установленной для каждого сообщения?

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

Иллюстрация обмена темами в RabbitMQ


person Jørn Schou-Rode    schedule 08.02.2013    source источник


Ответы (1)


Мне кажется, вы хотите сделать что-то вроде этого:

Configure.With(yourFavoriteContainer)
         .Transport(t => t.UseRabbitMq(...)
                          .ManageSubscriptions()) //< BAM!!1
         .(...)

что позволяет Ребусу воспользоваться тем фактом, что RabbitMqMessageQueue Ребуса реализует IMulticastTransport, что, в свою очередь, переключает обработку всей многоадресной рассылки на Rabbit.

Просто важно, чтобы все ваши конечные точки Rebus с поддержкой Rabbit согласились разрешить Rabbit ManageSubscriptions - иначе могут произойти странные вещи;)

Это означает, что

  • когда вы bus.Subscribe<SomeEvent>, вы привязываете тему с именем типа к входной очереди подписчика - например, "SomeEvent.SomeNamespace" -> myInputQueue
  • издатели публикуют события по теме, которая является названием типа - например, "SomeEvent.SomeNamespace"
  • право собственности на сообщение не принимается во внимание при подписке
  • Rabbit сделает тяжелую работу при многоадресной рассылке (что в основном и делают пользователи Rabbit).

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

Configure.With(yourFavoriteContainer)
         .Transport(t => t.UseRabbitMq(...)
                          .ManageSubscriptions()
                          .AddEventNameResolver(type => DecideTopic(type))
         .(...)

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

Имеет ли это смысл?

person mookid8000    schedule 08.02.2013
comment
Ваш ответ, похоже, предполагает реализацию стиля публикации / подписки. Я не уверен, что хочу этого. Все мои сообщения относятся к типам, которые имеют одну конечную точку для их обработки, только я хотел бы определить маршрут к этой конечной точке в терминах RabbitMQ, а не в web.config или коде. - person Jørn Schou-Rode; 08.02.2013
comment
Пример: наш сайт будет отправлять сообщения пяти разных типов. Все они попадают через один и тот же обмен в единую очередь на локальной установке RabbitMQ, откуда все они перемещаются в обмен на серверном блоке, где ключ темы / маршрутизации используется для разделения их на три отдельные очереди для трех конечных точек. Если позже мы захотим переместить одну из трех конечных точек в другой ящик, системный администратор может настроить это через веб-интерфейс RabbitMQ, не касаясь веб-сайта. Это безумие? - person Jørn Schou-Rode; 08.02.2013
comment
Тогда не вызывайте bus.Subscribe<SomeEvent> - а затем создавайте и поддерживайте привязку из тем, названных в честь довольно полного имени типа .NET - например, SomeNamespace.SomeEvent - person mookid8000; 08.02.2013
comment
Я добавил ManageSubscriptions() в свою конфигурацию и установил привязку Namespace.* к очереди в обмене Rebus на RabbitMQ. Когда я делаю bus.Publish(msg), кажется, что теперь ничего не происходит. В выводе консоли приложения указано «Sending Namespace.Type to Namespace.Type», но все, что я вижу на административных страницах RabbitMQ, - это нули :( - person Jørn Schou-Rode; 11.02.2013
comment
Хм, я не могу придумать причину, по которой это не сработает ... Это всего лишь предположение, но у вас случайно есть больше точек в названии типа? Например. действительно ли полное имя фактического типа реализации похоже на Namespace.Subnamespace.Type? Потому что тогда вы должны использовать # в качестве подстановочного знака в привязке. Символ * соответствует только одному элементу с разделителями, так как в 'A.B' будет соответствовать 'A. *', а 'A.B.C' не будет ... - person mookid8000; 11.02.2013
comment
Я должен тебе пива! Моя привязка с подстановочными знаками действительно была виновата. Кажется, сейчас все идет гладко. Огромное спасибо! - person Jørn Schou-Rode; 11.02.2013