Naming conventions in RabbitMQ
It was already known from that there are two major problems in programming: cache invalidation and naming things. The naming problem arises when we have to declare exchanges
and queues
in RabbitMQ.
Let’s take it for granted that there are no best names which suit every situation (except for i, j, n
and tmp
). Instead, consider the context in which we are working in.
There are always two parts: the first involves the service publishing a message
, and the second involves the consumers of that message. Both sides require an exchange to facilitate their tasks:
- The publisher utilizes the
exchange
as a “bucket” where it “drops” messages. - The consumer declares a queue and “binds” specific messages to the queue from the
exchange
. In other words, each time a message is “dropped” into the exchange, a copy of the message is routed to a queue.
The AMQP 0–9–1 Model has the following view of the world: messages are published to exchanges, which are often compared to post offices or mailboxes. Exchanges then distribute message copies to queues using rules called bindings.
Both sides require the exchange
, but who owns it (in our context, who declares it)? As in philosophy, depending on the answer, we can build different theories afterward. Is the exchange owned by?
- the publisher
- the consumer
- none of them, or both of them?
After a few years of experience with RabbitMQ, I have come to the conclusion that it is more convenient when the exchange
is declared by a publisher, so other consumers don’t have to worry about it. Obviously, the exchange declaration should be made once during app initialization, not every time a message is published.
What about the queue
? Well, the answer is simpler in this case: the publisher should not and cannot be responsible for queue declaration, as each queue has its own configuration for routing, priority setting, poisoned message handling, quorum strategy, etc. The consumer is the owner of a queue.
Considering the perspective of ownership regarding exchanges and queues, we can create the following template for naming exchanges and queues:
exchange_name = ${exchange_owner_name}.${category}
queue_name = ${queue_owner_name}.${queue_intent}
One last, but not least, thing is, often we want to run our test environments against production data. In our case, it implies that we want to have a queue
from the test environment that listens for messages from the production exchange.
# final version of a queue name template might be something like this
queue_name = ${queue_owner_name}.${app_env}.${queue_intent}
I hope that the perspective of ownership for naming exchanges
and queues
helps you maintain your projects and makes the integration process more human-readable and friendly.
Cheers.