3.2 KiB
← The on-ramp · Module README · The silent drop →
2. Four exchange types
A producer never publishes to a queue. It publishes to an exchange with a routing key,
and bindings decide where that lands. The whole topology is in
Topology.java as beans; RabbitAdmin
declares them when the connection opens.
Direct — exact match
Binding key new receives routing key new. Nothing else. This is the workhorse: one queue per
command type.
Fanout — routing key ignored entirely
Every bound queue gets a copy. audit.all and analytics.all both receive it, and the routing
key you passed is not consulted at all. Use it for broadcast; use it knowing that adding a queue
adds a full copy of the traffic.
Topic — wildcards over dot-separated words
* is exactly one word. # is zero or more. The distinction is the one people get
wrong, so here it is against a real broker
(docs/output/topic-wildcards.txt):
routing key orders.eu orders.high note
order.eu.high true true matches both
order.eu.low true false matches order.eu.* only
order.us.high false true matches order.#.high only
order.eu.west.high false true matches order.#.high only - * is one word
order.high false true matches order.#.high - # can be zero words
Bindings are order.eu.* and order.#.high. Two rows are worth pausing on:
order.eu.west.highdoes not matchorder.eu.*, because*matches one word andwest.highis two. Regex intuition says otherwise.order.highdoes matchorder.#.high, because#matches zero words. So a binding you wrote to mean "something in the middle" also matches "nothing in the middle".
Design routing keys most-general-to-most-specific (order.eu.west.high, not
high.order.eu.west), because # and * work left to right and a hierarchy you can bind
usefully is one that starts broad.
Headers — match a map, ignore the routing key
x-match=all requires every named header to be present and equal. x-match=any requires
one. From RoutingTest:
| Message headers | x-match=all queue |
x-match=any queue |
|---|---|---|
priority=high, region=eu |
yes | yes |
priority=high |
no | yes |
priority=high, region=us |
no | yes |
The third row is the one to remember: all matches on value, not on presence. A header that
is there with the wrong value fails the same way a missing one does.
Headers exchanges are slower than topic exchanges and much less common. Reach for them when the routing criteria are genuinely multi-dimensional and do not compose into a hierarchy.
The default exchange
Publishing to the empty exchange name "" routes by queue name, using the routing key as the
queue name. Every queue is implicitly bound to it. That is how
convertAndSend("", "orders.work", message) works, and it is the one piece of AMQP that behaves
like a magic constant.