RabbitMQ - Exchange / Queue / Routing Key
In RabbitMQ, producers send messages to an exchange, not directly to a queue. The exchange routes messages to one or more queues based on type and routing key (and headers for header exchange). Consumers consume from queues. This article explains the main exchange types and how routing works, with examples and a short table.
Overview
- Exchange: Receives messages and routes them to queue(s). Types: direct, topic, fanout, headers. Each exchange has a name and type.
- Queue: Holds messages for consumers. Queues are bound to exchanges with an optional binding key (and optional arguments). A message is delivered to a queue if the exchange type and binding match the message’s routing key (and headers if applicable).
- Routing key: A string set by the producer. Direct/topic exchanges use it to match bindings; fanout ignores it.
Example
Example 1: Direct exchange
- Binding: Queue bound with binding key
order.created. Exchange typedirect. Message with routing keyorder.createdgoes to that queue;order.cancelleddoes not (unless another binding exists). - Use when you want one routing key → one (or few) queues. Example: one queue per event type.
Example 2: Topic exchange
- Binding key: Can have wildcards.
#= zero or more words;*= exactly one word. Words separated by dots. Example: bindingorder.*matchesorder.created,order.cancelled; bindingorder.#matchesorder.created,order.payment.succeeded. - Use when you want to subscribe by pattern (e.g. all order events, or all payment events).
Example 3: Fanout exchange
- Routing: Ignores routing key. Every message is delivered to every queue bound to the exchange. Use for broadcast (e.g. cache invalidation to multiple services).
Example 4: Summary table
| Exchange type | Routing key used? | Typical use |
|---|---|---|
| direct | Yes, exact match | One key → one/few queues |
| topic | Yes, pattern (* and #) | Subscribe by pattern |
| fanout | No | Broadcast to all bound queues |
| headers | Optional (header match) | Routing by message headers |
Core Mechanism / Behavior
- Binding: A binding links an exchange to a queue (with optional binding key and arguments). One queue can be bound to multiple exchanges; one exchange can be bound to many queues.
- Default exchange: Nameless exchange; every queue is bound with its name as routing key. Sending to that exchange with routing key = queue name delivers to that queue.
- Persistence: Queue and message can be durable so they survive broker restart. Producer can set delivery mode persistent.
Key Rules
- Choose exchange type by routing need: direct for exact key, topic for pattern, fanout for broadcast. Use default exchange only for simple “send to queue by name” cases.
- Name queues and routing keys consistently (e.g.
order.created,order.payment.succeeded) so topic bindings are predictable. Use dead-letter exchange (DLX) and dead-letter queue for failed messages. - Set TTL and max length on queues if you need to limit retention or backlog; use consumer prefetch to control how many unacked messages each consumer has.
What's Next
See Retry and DLQ Strategy for failed messages and DLQ. See MQ Basics for async and decoupling. See Kafka Core Concepts for a comparison (Kafka has no exchange; routing = topic + partition).