What is Message
RPC (Remote Procedure Calls) are unreliable. Reasons are as below
1. Remote Procedure No Server (Server is down)
2. Remote Procedure Call No Response from Server
3. Remote Procedure Call Too Many Calls. The server has handled all these requests synchronously. But nowadays we have so many asynchronous libraries to mitigate this. But still depends on the load on the server.
Messaging
So to get around some of these problems, we can use messaging. So with messaging what we do is we impose a middleman, and that middleman is a message queue, or more generally a message broker
client can drop a message onto the queue, and depending on the message broker, we can guarantee that we know that message has been delivered or not. The server asynchronously picks up the message from the queue, and the server can then process that message. Now, depending on the type of processing, we may or may not care whether that message has been processed or not. We may or may not care synchronously whether that message has been processed or not. So we may have this fire‑and‑forget scenario, I'm just going to send out a message and let some server at some point deal with that message. And at this point as well, the message broker can guarantee that the message will be delivered. So if the server takes the message off the queue and halfway through processing blows up and hasn't yet acknowledged the message, that message will get pushed back onto the queue, and at some point it will be re-delivered. So message brokers allow redelivery of messages. So we have this idea of guaranteed delivery, where we know a server will be able to process this message at some point.
Introduction to RabbitMQ
Where does RabbitMQ fit?
- AMQP
- Many client libraries
- Java, Python, C#, etc.
Concepts in RabbitMQ
What are Exchanges ?
What Queues are ?
How we can use Exchanges and Queues together to publish and consume messages ?
So once we have Exchanges and Queues, we have to bind these together. How bindings work ?
How messages are delivered and how they are consumed ?
Publishers/Producers talk to Exchanges, Consumers talk to Queues, Publishers publish messages to Exchanges, and Consumers consume those messages from Queues.
How we bind queues to exchanges and how we exchange these messages ?
The Exchanges are then bound to Queues, and as we can see, we can have multiple Queues bound to a given Exchange.
How this binding works and how we can bind these queues to an exchange ?
Publisher publishes into an exchange depending on the binding and some routing information in the published message. Those messages will end up on a Queue somewhere or maybe more than one Queue. And the Consumer will then consume the messages from those Queues. And Consumers can consume from many Queues if they need to.
Exchanges
There are different types of Exchanges
- Topic Exchange
- Fanout Exchange
- Direct Exchange
- Headers Exchange
- Dead Letter Exchange
Each of these exchanges deals with messages differently.
So Topic Exchanges, for example, allow us to route messages depending on some topic information.
Direct Exchanges deliver a message directly to a Queue.
Fanout Exchanges can deliver messages to multiple Queues and have multiple processes for those messages.
Queues
A queue is an ordered collection of messages, and consumers read messages from queues. And a given consumer can process multiple queues if necessary. So we're not limited to a single queue per consumer. And essentially with the consumer when it reads from a queue, it doesn't necessarily know what sort of exchange delivered messages to that queue. All the consumer cares about is that it can get a message from a queue and somehow process that message.
So what an exchange is, it can have different behaviors and different exchange types of different behavior. Queues can have different behavior as well. And with queues, we can define different properties on different queues. So queues have a name that we can use. Queues can be marked as Durable. So a
Durable Queue is a queue that will survive a service restart.
Queues can have other properties as well. So for example, we can mark a queue as exclusive. We can define the delete semantics on the queue, and there are other arguments we can use when we create the queue.
Binding
So if queues are used by consumers and exchanges are used by publishers and we've said that the consumer doesn't really care about the exchange, how does RabbitMQ know which messages that are published to an exchange go onto which queues to be consumed by a consumer? Well, that's done via something called a binding. So queues are bound to exchanges. And when we do the binding, we specify three things.
- Consists of exchange
- Routing Key
- Queue
We can specify the exchange to bind to, the queue we want to bind to that exchange, and something called a Routing Key. And the routing key defines which messages that come into that exchange get posted to this queue. So not all messages that go to an exchange get passed on to all the queues that are bound to that exchange. The messages that are passed on to a specific queue are defined via the routing key. And different exchanges will behave differently with regard to this routing key. For example, a fanout exchange ignores the routing key, and it sends all messages to all queues that are bound to that exchange. Queue is bound to an Exchange via a Routing Key. fanout exchange ignores the routing key.
Because of the separation between exchanges and queues and because of this abstraction of the routing key, we get a lot of flexibility in the way that messages can be processed by RabbitMQ and, therefore, the way that we can process those messages within our application.