RabbitMQ Designs

RabbitMQ is used to make communication between services by messages. Using this we can achieve event-driven architecture. Most people have experienced RabbitMQ with the Simple Push to Pull(P2P) mechanism. They will simply push the messages into the queue and another service will consume those messages. It's a kind of one-to-one mapping between the producer and consumer. People have read the exchanges and routing, but they didn't have the chance to implement it or map it into their use cases. I have started my RabbitMQ development with a simple P2P mechanism later it has enhanced with one too many relationships using exchanges and routing.

P2P

I need to send an SMS to the end-user in my eCommerce application once the user confirmed the order. I have created a separate service to send an SMS based on the RabbitMQ message. Order service will push the message into the SMS queue once the user confirmed the order.

SMS service will read the message from the SMS queue and send an SMS to the corresponding user based on the message details. This is a simple use case so I didn't use any exchange and routing key. I have used my queue name as my routing key. Most of the people will meet this kind of use case. So they will use a simple P2P mechanism in their architectures.

One to Many (Exchange)

Later I have upgraded my application to send the confirmation message via email, push along with SMS. We have separate services for email, Push, and SMS. Each service will listen to messages from their Queues. There are two ways we can push the same messages into multiple queues.

  1. Publish the same message repeatedly on different queues - But it's not recommended.
  2. Publish the single message and each queue will get a copy of it - recommended.

We can achieve option #2 by Exchanges. We can configure multiple queues into a single exchange using exchange type and routing key. An exchange will receive the messages and push them into the queues based on the exchange type and routing key. 

In my use case, I have configured my Email, Push, and SMS queue into my notification exchange using the fanout exchange type. So order service will push the messages into my notification exchange and the exchange will push the copy of the message into each queue by fanout exchange type. Notification services will send the confirmation message to end users via email, SMS, and Push.

One to Many (Routing)

Later I have added a new use case like we need to send an SMS to the end-user whenever the user logged into the system as part of cybersecurity. The current system will have the capability to send the notification in a different medium for a single message. I need to send Order Confirmation messages in all mediums but Logged in information only via SMS alone.

I have achieved my use case using routing. I have created a new exchange notfication_key_routing using the direct exchange type. After that, I have bound the SMS queue with this exchange using routing key SMS. From my user service, I have pushed the message to notfication_key_routing exchange with exchange key as SMS. So my SMS queue will receive the message from two exchanges

  1. From notification exchange using fanout type for order confirmation
  2. From notfication_key_routing using direct type for the user logged In

Still, we are improving our message flow and architecture by reducing the number of exchanges, queues, routing keys, and Dead Lead exchanges with the Retry mechanism.