It is sometimes desirable to let clients handle messages that an exchange was unable to route (i.e. either because there were no bound queues our no matching bindings). Typical examples of this are
- detecting when clients accidentally or maliciously publish messages that cannot be routed
- “or else” routing semantics where some messages are handled specially and the rest by a generic handler
RabbitMQ’s Alternate Exchange (“AE”) feature addresses these use cases.
For any given exchange, an AE can be defined by clients using the exchange’s arguments, or in the server using policies. In the case where both policy and arguments specify an AE, the one specified in arguments overrules the one specified in policy.
When creating an exchange the name of an AE can be optionally supplied in the exchange.declare method’s arguments table by specifying a key of ‘alternate-exchange’ and a value of type ’S’ (string) containing the name.
When an AE has been specified, in addition to the usual configure permissions on the declared exchange, the user needs to have read permissions on that exchange and write permissions on the AE.
Map<String, Object> args = new HashMap<String, Object>(); args.put("alternate-exchange", "my-ae"); channel.exchangeDeclare("my-direct", "direct", false, false, args); channel.exchangeDeclare("my-ae", "fanout"); channel.queueDeclare("routed"); channel.queueBind("routed", "my-direct", "key1"); channel.queueDeclare("unrouted"); channel.queueBind("unrouted", "my-ae", "");
In the above fragment of Java code we create a direct exchange 'my-direct’ that is configured with an AE called 'my-ae’. The latter is declared as a fanout exchange. We bind one queue 'routed’ to 'my-direct’ with a binding key of 'key1’, and a queue 'unrouted’ to 'my-ae’.
To specify an AE using policy, add the key 'alternate-exchange’ to a policy definition. For example:
This will apply an AE of “my-ae” to the exchange called “my-direct”. Policies can also be defined using the management plugin, see the policy documentation for more details.
Whenever an exchange with a configured AE cannot route a message to any queue, it publishes the message to the specified AE instead. If that AE does not exist then a warning is logged. If an AE cannot route a message, it in turn publishes the message to its AE, if it has one configured. This process continues until either the message is successfully routed, the end of the chain of AEs is reached, or an AE is encountered which has already attempted to route the message.
For example if we publish a message to 'my-direct’ with a routing key of 'key1’ then that message is routed to the 'routed’ queue, in accordance with the standard AMQP behaviour. However, when publishing a message to 'my-direct’ with a routing key of 'key2’, rather than being discarded the message is routed via our configured AE to the 'unrouted’ queue.
The behaviour of an AE purely pertains to routing. If a message is routed via an AE it still counts as routed for the purpose of the 'mandatory’ flag, and the message is otherwise unchanged.