Use one durable topic exchange, for example events. Give routing keys a fixed structure such as <entity>.<action>.<region>. Examples: order.shipped.eu or order.created.us.
Each service declares its own durable queue and binds it with a pattern:
- Email queue: binds with
order.#. Every order event reaches it, whatever comes afterorder. - EU warehouse queue: binds with
order.shipped.eu. - Audit queue: binds with
#, which matches every routing key.
All instances of one service consume from that service's queue. So they share the work between them.
Decide the key format up front and document it. Bindings depend on the word positions. Adding a region later is cheap. But changing the order of the words breaks existing bindings.
- Use one topic exchange with a structured routing key.
- Email binds with order.#, the EU warehouse with order.shipped.eu, and audit with #.
- Each service has one queue, and its instances compete for messages on it.
- The routing key format is a contract, because word positions matter.