Chapter 2. Exchanges

In the AMQP 0-10 model, a message producer sends messages to an exchange, which immediately distributes messages to queues. The exchange decides which queues should receive a message based on exchange type and the queue bindings, which bind a queue to an exchange. The AMQP 0-10 model is discussed in Section 1.2, “The AMQP 0-10 Model”.
In MRG Messaging there are four standard exchange types and a custom exchange type:

AMQP 0-10 Exchange Types

  • Fanout
  • Direct
  • Default
  • Topic
  • Headers
  • XML Exchange (A Custom Exchange)
The semantics of these exchange types are described in the following sections.

2.1. Exchange Types

In the AMQP 0-10 model, exchange types differ only in the algorithm used to determine which queues should receive a message. This section describes the algorithm used for each exchange type.

2.1.1. Fanout Exchange

The simplest exchange type is a Fanout exchange, which sends each message to every queue bound to the exchange.
Fanout Exchange
A Fanout exchange sends messages to every queue bound to the exchange.
Every AMQP 0-10 broker contains one predeclared fanout exchange named amq.fanout. Additional fanout exchanges can be declared as needed.

2.1.2. Direct Exchange

A message producer can specify a routing key for a message. A routing key is simply a string that indicates a kind of message. In a Direct exchange, a binding specifies a binding key, and an exchange delivers a message to a bound queue if the message's routing key is identical to the queue's binding key.
Direct Exchange
A Direct exchange sends a message to a queue if the message's routing key is identical to the binding key for the queue.
Every AMQP 0-10 broker contains one predeclared direct exchange named amq.direct. Additional direct exchanges can be declared as needed.

2.1.3. Default Exchange

A default exchange uses the name of a queue as the binding key. If a message producer sends a message to the default exchange, and the routing key in the message is the name of a queue, the message is delivered to that queue. In the AMQP 0-10 model, every queue is automatically bound to the default exchange.
In AMQP 0-10, every exchange except the default exchange has a name. If a message is sent to a messaging broker without specifying an exchange name, it is sent to the default exchange. Every AMQP 0-10 broker has one predeclared default exchange, which has no name. It is not possible to declare additional default exchanges.

2.1.4. Topic Exchange

A Topic exchange is similar to a Direct exchange, but uses keys that contain multiple words separated by a . delimiter. A message producer might create messages with routing keys like usa.news, usa.weather, europe.news, and europe.weather.
Binding keys for a Topic exchanges can include wildcard characters: a # matches one or more words, a * matches a single word. Typical bindings use binding keys like #.news (all news items), usa.# (all items in the USA), or usa.weather (all USA weather items).
The exchange routes messages to the relevant queue or queues, depending on matches between the routing and binding keys.
Topic Exchange
A Topic exchange can use multi-part routing keys and bindings that include wildcards. A topic exchange sends a message to a queue if the message's routing key matches the binding key for the queue, using wildcard matching.

Example 2.1. Using multi-part keys with a topic exchange

This example demonstrates the use of multi-part keys in a topic exchange
Suppose a message producer creates four messages concerning news and weather in the United States of America and Europe. The producer creates four different routing keys for the messages, each of which contains two parts. The two parts of the routing keys are separated with a . (period) character:
  1. usa.news
  2. usa.weather
  3. europe.news
  4. europe.weather
There are currently four queues bound to the topic exchange. The four queues collect information on:
  1. Everything related to the USA
  2. All news
  3. All weather
  4. Everything related to Europe
These are defined as a two-part binding key, with the # (pound) character as a wildcard:
  1. usa.#
  2. #.news
  3. #.weather
  4. europe.#
In this example, the message with the routing key of usa.weather will be delivered to two queues - usa.# and #.weather. Similarly, the message with the routing key of europe.news will be delivered to the queues with the binding keys europe.# and #.news

Every AMQP 0-10 broker contains one predeclared topic exchange named amq.topic. Additional topic exchanges can be declared as needed.

2.1.5. Headers Exchange

AMQP 0-10 provides a headers exchange, which allows simple queries on properties in the headers of a message. The binding contains a list of header names and properties, and an argument specifying whether 'all' semantics are used (all header fields must match in order for the message to match) or 'any' semantics (if any header field matches, the message satisfies the binding.
Every AMQP 0-10 broker contains one predeclared headers exchange named amq.match. Additional header exchanges can be declared as needed.

2.1.6. Custom Exchange Types

AMQP allows implementations to provide exchange types that are not defined in the standard. These exchange types are referred to as custom exchange types. Custom exchanges are not predeclared.
MRG Messaging provides an XML Exchange, which can route XML messages based on their content. The bindings for an XML Exchange use an XQuery, which is applied to the content and headers of each message to determine whether the message should be routed. For instance, suppose the messages sent to an XML exchange contain weather reports like this one:
<weather>
    <station>Raleigh-Durham International Airport (KRDU)</station>
    <wind_speed_mph>16</wind_speed_mph>
    <temperature_f>70</temperature_f>
    <dewpoint>35</dewpoint>
</weather>

An XML Exchange binding specifies a binding key and an XQuery. A message matches the binding if its routing key matches the binding key and the XQuery evaluates to true.
The XQuery used in an XML Exchange binding can specify a set of conditions based on the structure of the XML. For instance, the following binding matches messages for Raleigh-Durham, with a temperature greater than 50 degrees, a temperature comfortably above the dewpoint, and wind speeds within a range suitable for small sailboats:
let $w := ./weather
   return $w/station = 'Raleigh-Durham International Airport (KRDU)'
      and $w/temperature_f > 50
      and $w/temperature_f - $w/dewpoint > 5
      and $w/wind_speed_mph > 7
      and $w/wind_speed_mph < 20

The XML Exchange can also query headers. Each header is bound to an external XQuery variable that has the same name as the header. The query for a binding must declare this external variable in order to use it. A single query may contain conditions on both headers and XML content.
The following query matches a message if the header control contains the value 'end', or if the XML content specifies an odd numbered message ID:
declare variable $control external;
./message/id mod 2 = 1 or $control = 'end'