3

We are using Rebus 4.2.1 and RabbitMQ

What we want to achieve is to have handlers on three (or more) instances all react to the same message.

As far as I understood (which may be wrong) - .Publish on the IBus interface should do exactly that (and we have been running with that on MSMQ).

Is there something I am missing with how RabbitMQ works?

(EDIT: I think the term used in RabbitMQ is a "fanout" style message)

EDIT2: mookid8000 put me on the right track - the issue was that each replica was asking for the same queue. As soon as I made that unique - everything started working as intended (and expected).

Goblin
  • 7,970
  • 3
  • 36
  • 40
  • You should publish messages to a fanout exchange. This is well-documented in the RabbitMQ tutorials: https://www.rabbitmq.com/tutorials/tutorial-three-python.html – Luke Bakken Sep 27 '18 at 01:57
  • @LukeBakken Problem is that I am not using RabbitMQ directly. But you are correct :-) – Goblin Oct 05 '18 at 11:50

1 Answers1

2

With Rebus + RabbitMQ, it's pretty simple, because RabbitMQ has native support for topic-based pub/sub messaging.

In each subscriber, you simply call

await bus.Subscribe<YourEvent>();

which will make Rebus generate a topic string out of your event type, and then bind it to the subscriber's input queue, and then in the publisher you

await bus.Publish(new YourEvent(...));

and then each subscriber will get a copy of the event in its input queue.

Underneath the covers, Rebus uses RabbitMQ's "Topic Exchange" exchange type to make this work.

mookid8000
  • 18,258
  • 2
  • 39
  • 63
  • Thanks for the answer - however, this is exactly what we are doing and what we are seeing with three identical consumers (apart from being on separate machines) is that only one of them gets their handler called for each message published. – Goblin Sep 24 '18 at 09:27
  • Just to explain the setup - we have three webfronts that each calls this: var bus = Configure.With(new CastleWindsorContainerAdapter(container)) .Logging(l => l.Log4Net()) .Routing(t => t.TypeBased().AddEndpointMappingsFromAppConfig()) .Transport(t => t.UseRabbitMq(endpoints, "Xena.Web")) .Start(); on startup – Goblin Sep 24 '18 at 09:30
  • 1
    if only one of the instances gets the event, it must be because they're receiving messages from the same queue.....? are they THAT identical? – mookid8000 Sep 24 '18 at 09:46
  • They are completely identical (it is just three instances behind a loadbalancer) – Goblin Sep 24 '18 at 09:54
  • 1
    well in that case, you cannot distribute the same message to all of them – they will always end up competing for each message you put into the queue, which is nice, because then you can trivially distribute work evenly among them (that's the ["Competing Consumers"](https://www.enterpriseintegrationpatterns.com/patterns/messaging/CompetingConsumers.html) pattern) – mookid8000 Sep 24 '18 at 11:17
  • Yeah - I had a facepalm moment there :) Updated my question to reflect this. – Goblin Sep 24 '18 at 11:44