Skip to main content

RabbitMQ

https://www.rabbitmq.com/
RabbitMQ Tutorials

Terminology

  • Producer: Application that sends the messages.
  • Consumer: Application that receives the messages.
  • Queue: Buffer that stores messages.
  • Message: Information that is sent from the producer to a consumer through RabbitMQ.
  • Connection: A connection is a TCP connection between your application and the RabbitMQ broker.
  • Channel: A channel is a virtual connection inside a connection. When you are publishing or consuming messages from a queue – it’s all done over a channel.
  • Exchange: Receives messages from producers and pushes them to queues depending on rules defined by the exchange type. To receive messages, a queue needs to be bound to at least one exchange.
  • Binding: A binding is a link between a queue and an exchange.
  • Routing key: The routing key is a key that the exchange looks at to decide how to route the message to queues. The routing key is like an address for the message.
rabbitm-multiple-queues.png

Queue

  • Producer - a program that sends messages is a producer (P).
  • Queue - messages can be stored inside a Queue. Many producers can send messages that go to one queue, and many consumers can try to receive data from one queue.
  • Consumer - a consumer (C) is a program that mostly waits to receive messages.
rabbitmq-queue-01.png
  • Exchange - on one side it receives messages from producers and the other side it pushes them to queues.
rabbitmq-exchange-01.png

The exchange must know exactly what to do with a message it receives. Should it be appended to a particular queue? Should it be appended to many queues? Or should it get discarded. The rules for that are defined by the exchange type.

Exchanges

RabbitMQ is a versatile message broker that enables complex routing scenarios between producers and consumers. It plays a pivotal role in modern software architectures, facilitating asynchronous communication and enhancing scalability. At the heart of RabbitMQ’s power are its exchanges, which control how messages are routed to queues.

Exchanges are RabbitMQ entities where messages are sent before arriving at queues. The type of exchange determines how a message is routed. There are four main types of exchanges in RabbitMQ:

  • direct
  • topic
  • headers
  • fanout

Direct Exchange

When a message is published to a direct exchange, it includes a routing key — a string identifier. The exchange then forwards the message to all queues that are bound to it with a matching routing key. If no queue matches the routing key, the message is discarded (unless configured otherwise, such as returning the message to the producer or storing it in a dead letter queue).

  • Routing Key: A message attribute used by the exchange to route messages to the correct queue. It’s like an address that tells the exchange where to deliver the message.
  • Binding Key: When a queue binds to an exchange, it specifies a binding key. It’s this key that the exchange uses to match against the message’s routing key.

Topic Exchange

Topic exchanges route messages to queues based on wildcard matches between the routing key and the routing pattern, which is specified by the queue binding. Messages are routed to one or many queues based on a matching between a message routing key and this pattern.

The routing key must be a list of words, delimited by a period (.). Examples are agreements.us and agreements.eu.stockholm which in this case identifies agreements that are set up for a company with offices in lots of different locations. The routing patterns may contain an asterisk (“”) to match a word in a specific position of the routing key (e.g., a routing pattern of "agreements...b." only match routing keys where the first word is "agreements" and the fourth word is "b"). A pound symbol (“#”) indicates a match of zero or more words (e.g., a routing pattern of "agreements.eu.berlin.#" matches any routing keys beginning with "agreements.eu.berlin").

The consumers indicate which topics they are interested in (like subscribing to a feed for an individual tag). The consumer creates a queue and sets up a binding with a given routing pattern to the exchange. All messages with a routing key that match the routing pattern are routed to the queue and stay there until the consumer consumes the message.

The default exchange AMQP brokers must provide for the topic exchange is "amq.topic".

Routing patterns in Topic Exchange

  • A routing key in Topic Exchange must consist of Zero or more words delimited by dots e.g. health.education.
  • A routing key in topic exchange is often called as a routing pattern.
  • A routing pattern is like a regular expression with only *, . and # allowed.
  • The symbol star (*) means exactly one word allowed.
  • Similarly, the symbol hash (#) means zero or more number of words allowed.
  • The symbol dot (.) means – word delimiter. Multiple key terms are separated by the dot delimiter.
  • If a routing pattern is health.*, it means any message sent with the routing key health as the first word will reach the queue. For example, health.education will reach this Queue, but sports.health will not work.

Headers Exchange

A headers exchange routes messages based on arguments containing headers and optional values. Headers exchanges are very similar to topic exchanges, but route messages based on header values instead of routing keys. A message matches if the value of the header equals the value specified upon binding.

A special argument named "x-match", added in the binding between exchange and queue, specifies if all headers must match or just one. Either any common header between the message and the binding count as a match, or all the headers referenced in the binding need to be present in the message for it to match. The "x-match" property can have two different values: "any" or "all", where "all" is the default value. A value of "all" means all header pairs (key, value) must match, while value of "any" means at least one of the header pairs must match. Headers can be constructed using a wider range of data types, integer or hash for example, instead of a string. The headers exchange type (used with the binding argument "any") is useful for directing messages which contain a subset of known (unordered) criteria.

The default exchange AMQP brokers must provide for the topic exchange is "amq.headers".

The Headers matching algorithm

- There are 2 types of headers matching allowed which are any (similar to logical OR) or all (similar to logical AND).
- They are represented in the bindings as { "x-match", "any" ..} or { “x-match”, “all” ..}.
- The x-match = any means, a message sent to the Exchange should contain at least one of the headers that Queue is linked with, then the message will be routed to the Queue.
- On the other hand, if a queue is bound with headers has x-match = all, messages that have all of its listed headers will be forwarded to the Queue.
- You can see in the above diagram if a message with header {"h1": "Header1"} is sent to my-header-exchange, it will be routed to both HealthQ and EducationQ.
- Only when the message has both the h1 and h2 headers with correct values, it will be forwarded to SportsQ, HealthQ and EducationQ as well.

Fanout Exchange

A fanout exchange copies and routes a received message to all queues that are bound to it regardless of routing keys or pattern matching as with direct and topic exchanges. The keys provided will simply be ignored.

Fanout exchanges can be useful when the same message needs to be sent to one or more queues with consumers who may process the same message in different ways.

The image to the right (Fanout Exchange) shows an example where a message received by the exchange is copied and routed to all three queues bound to the exchange. It could be sport or weather updates that should be sent out to each connected mobile device when something happens, for instance.

The default exchange AMQP brokers must provide for the topic exchange is "amq.fanout".