Message brokers and the AMQP model

RabbitMQ · Essentials · 7 min

Every RabbitMQ design decision builds on this model, and it differs from simply 'putting messages in a queue'.

A message broker sits between applications. Instead of calling a service directly, a producer publishes a message and moves on; a consumer processes it later. This decouples services in time and load: if consumers are slow or down, messages wait in the broker.

RabbitMQ's model, from the AMQP 0-9-1 protocol:

  • Connection: a long-lived TCP connection from an application to the broker. Inside it, lightweight channels carry the actual operations; use one connection per process and a channel per thread.
  • Exchange: where producers publish. An exchange never stores messages; it routes them using its type and the message's routing key.
  • Queue: an ordered buffer that stores messages until a consumer takes them.
  • Binding: a rule linking an exchange to a queue, optionally with a binding key or pattern.
  • Virtual host (vhost): a namespace isolating exchanges, queues and permissions.

Messages consist of a body (bytes; RabbitMQ doesn't care about the format) and properties such as content type, headers, delivery mode and message ID.

Typical uses are background jobs (send email, resize images), distributing events to several services, and buffering bursts. Each message in a queue is delivered to one consumer; to deliver to several services, bind several queues to an exchange.

Example

# Flow of one message
#
#  producer --publish(routing_key="order.created")--> [exchange "events" (topic)]
#                                                        |  binding "order.*"
#                                                        v
#                                                  [queue "billing"] --> consumer A
#                                                        |  binding "#"
#                                                        v
#                                                  [queue "audit"]   --> consumer B
#
# Each queue gets its own copy; within a queue each message goes to one consumer.
rabbitmqctl list_exchanges name type | head -4
# name                type
#                     direct      <- the default exchange
# amq.direct          direct
# amq.fanout          fanout

Remember

  • Producers publish to exchanges; exchanges route to queues via bindings
  • Queues store messages; each message in a queue goes to one consumer
  • One connection per process, channels inside it

Watch out for

  • Opening a new connection per message published; connections are expensive, keep them long-lived.

Check yourself

  1. Two services must both receive every 'order created' message. What do you need?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.rabbitmq.com/tutorials/amqp-concepts

Builds on

Nothing: this is a foundation.

Unlocks