LuisRococo
LuisRococo

Reputation: 193

Do i require a queue for each consumer in rabbitMQ?

I have the next problem, I have three programs and they should send a notification (message) to rabbitMQ when they modify a database, also each program should receive that notification so they know about that modification to the database.

I am new on using rabbitMQ so I don't know the way of working, I kinda understand the "hello world" tutorial on the official page and when I tried to use it (one queue) with multiple consumers, only one of them received the notification, so I am guessing I need to use a queue for each consumer but I want to know if that is the correct way to work with rabbitMQ in this situation.

As extra information about my project, I need each consumer to receive the last message sent, they should not care about past messages, so if a consumer is not available when it begins working it should not receive the spam of all the past notifications.

Upvotes: 1

Views: 1238

Answers (1)

Oran Gerbovski
Oran Gerbovski

Reputation: 319

Yes, you do need a queue for each consumer.

You can use fanout exchange

channel.ExchangeDeclare("database", ExchangeType.Fanout);

and regarding your "extra information"

As extra information about my project, I need each consumer to receive the last message sent, they should not care about past messages, so if a consumer is not available when it begins working it should not receive the spam of all the past notifications.

You can use a non-durable, exclusive, autodelete "Temporary queue" as suggested in the official tutorial on this page

channel.QueueDeclare();

Here are two quotes from this page:

  1. ... We're also interested only in currently flowing messages not in the old ones.

  2. ... whenever we connect to Rabbit we need a fresh, empty queue. To do this we could create a queue with a random name, or, even better - let the server choose a random queue name for us.

And then finally bind the queue to the exchange:

channel.QueueBind(queue: queueName, exchange: "database", routingKey: "");

All together:

channel.ExchangeDeclare("database", ExchangeType.Fanout);
var queueName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queueName,
                  exchange: "database",
                  routingKey: "");

Of course each program will have a publisher logic, and subscriber logic. And if we named the 3 programs with "A", "B" & "C", and then use the online simulator tool http://tryrabbitmq.com/, we get the following routing topology

==============

Hint

In the future you might want to differentiate between different types of database changes (e.g. schema changed, data changed) For that i would use a "database" topic exchange and routing keys per notification type. The rest will stay the same:

channel.ExchangeDeclare("database", ExchangeType.Topic);
var queueName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queueName,
                  exchange: "database",
                  routingKey: "schema.changed");

Upvotes: 1

Related Questions