zangw
zangw

Reputation: 48396

Should exchange or queue be declared multiple times in RabbitMQ?

I discuss the RabbitMQ design with my colleague between Server A and Server B, here is the flow chart as following.

enter image description here

Server A sends messages to Server B through exchange A and Queue B, and receives messages from Server B through Queue A. vice versa for Server B.

There are two classes in Server A implemented with C++; one is sender, the other is receiver. The same code structure is for Server B implemented with JavaScript.

For the sender and receiver in Server A. My colleague's idea is:

The same logic in Server B.

However, I do NOT think Queue B and Exchange B should be declared in Server A. They are should be declared in Server B.

Finally, I implement it following my colleague's idea, due to he has done some related work before.


Today, the Server A hang at the function amqp_queue_declare in Sender module during test, but it works well after restarting RabbitMQ. So I doubt the my colleague's idea for the initialization of Sender.

My thought:

Could someone tell me is there anything wrong with my thought? or is there better solution?


Edit: answer questions from @Sigismondo

Upvotes: 7

Views: 3968

Answers (1)

Sigi
Sigi

Reputation: 4926

It's perfectly legit that both servers declare the queue and the exchange, and it's usually the preferred approach, when dealing with named queues: usually you want producers and consumers be decoupled, and letting both declare (i.e.: create if missing) the queues and the exchange, you let both work correctly and you have the guarantee that no messages are lost, in case the other peer has not been started yet, even on a RabbitMQ fresh install.

In particular it's important that:

  • the consumer declare the queues from which must consume messages (or it won't be able to consume from them).

  • the producer declare the queues and the exchanges to which it produces before producing messages (or they will be lost, in case no consumer has created the queues).

This is the typical approach used when using named queues, that seems what you are doing here.

Now, in case you want the messages to be forgotten in case the consumer is not there, than the producer won't declare any queue: the consumer can create a temporary queue and bind it to the exchange.

Finally, if this is the case, and you want to be notified in case there are not consumers (and no queues bound to the exchange), you can use alternate exchanges.

So, you see it: there are some options that you can use, but there is a rationale for each one: you must choose which one to use based on the specific problem - and that has not been qualified enough by your explanation: even if very detailed it's missing some aspects:

  • do all the messages need to be delivered to the consumer A/B?
  • does the consumer A/B need to be notified in case some messages are lost?
  • what is the intended behavior in case the consumer A/B is not reachable?
  • what is the intended behavior in case the producer A/B is down?

However amqp_queue_declare should not hang at all: if this is the case you are facing a bug or I have no idea what, but that's not the intended behavior for it, to my knowledge.

Upvotes: 11

Related Questions