Este contenido no está disponible en el idioma seleccionado.
Chapter 4. Addresses, Queues, and Topics
AMQ Broker has a unique addressing model that is both powerful and flexible and that offers great performance. The addressing model comprises three main concepts: addresses, queues and routing types.
An address represents a messaging endpoint. Within the configuration, a typical address is given a unique name, 0 or more queues, and a routing type.
A queue is associated with an address. There can be multiple queues per address. Once an incoming message is matched to an address, the message is sent on to one or more of its queues, depending on the routing type configured. Queues can be configured to be automatically created and deleted.
A routing type determines how messages are sent to the queues associated with an address. A AMQ Broker address can be configured with two different routing types.
If you want your messages routed to… | Use this routing type … |
---|---|
A single queue within the matching address, in a point-to-point manner. | anycast |
Every queue within the matching address, in a publish-subscribe manner. | multicast |
An address must have at least one routing type.
It is possible to define more than one routing type per address, but this typically results in an anti-pattern and is therefore not recommended.
If an address does use both routing types, however, and the client does not show a preference for either one, the broker typically defaults to the anycast
routing type. The one exception is when the client uses the MQTT protocol. In that case, the default routing type is multicast
.
4.1. Address and Queue Naming Requirements
You should be aware of the following requirements when you configure addresses and queues:
To ensure that a client can connect to a queue regardless of which wire protocol it uses, your address and queue names should not include any of the following characters:
&
::
,
?
>
-
The
#
and*
characters are reserved for wildcard expressions. For more information, see the section called “AMQ Broker Wildcard Syntax”. - Address and queue names should not include any spaces.
-
To separate words in an address or queue name, use the configured delimiter character (the default is the
.
character). For more information, see the section called “AMQ Broker Wildcard Syntax”.
4.2. Configuring Point-to-Point Messaging
Point-to-point messaging is a common scenario in which a message sent by a producer has only one consumer. AMQP and JMS message producers and consumers can make use of point-to-point messaging queues, for example. Define an anycast
routing type for an address
so that its queues receive messages in a point-to-point manner.
When a message is received on an address using anycast
, AMQ Broker locates the queue associated with the address and routes the message to it. When consumers request to consume from the address, the broker locates the relevant queue and associates this queue with the appropriate consumers. If multiple consumers are connected to the same queue, messages are distributed amongst each consumer equally, providing the consumers are equally able to handle them.
Figure 4.1. Point-to-Point
Procedure
-
Open the file
BROKER_INSTANCE_DIR/etc/broker.xml
for editing. Wrap an
anycast
configuration element around the chosenqueue
element of anaddress
. Ensure the value ofaddress name
andqueue name
elements are same.<configuration ...> <core ...> ... <address name="durable"> <anycast> <queue name="durable"/> </anycast> </address> </core> </configuration>
4.3. Configuring Publish-Subscribe Messaging
In a publish-subscribe scenario, messages are sent to every consumer subscribed to an address. JMS topics and MQTT subscriptions are two examples of publish-subscribe messaging. When a message is received on an address with a multicast
routing type, AMQ Broker routes a copy of the message to each queue. To reduce the overhead of copying, each queue is sent only a reference to the message and not a full copy.
Figure 4.2. Publish-Subscribe
Procedure
-
Open the file
BROKER_INSTANCE_DIR/etc/broker.xml
for editing. Add an empty
multicast
configuration element to the chosen address.<configuration ...> <core ...> ... <address name="topic.foo"> <multicast/> </address> </core> </configuration>
(Optional) Add one more
queue
elements to the address and wrap themulticast
element around them. This step is typically not needed since the broker automatically creates a queue for each subscription requested by a client.<configuration ...> <core ...> ... <address name="topic.foo"> <multicast> <queue name="client123.topic.foo"/> <queue name="client456.topic.foo"/> </multicast> </address> </core> </configuration>
4.4. Configuring a Point-to-Point Using Two Queues
You can define more than one queue on an address by using an anycast
routing type. Messages semt to an anycast
address are distributed evenly across all associated queues. By using Fully Qualified Queue Names, which are described later, you can have clients connect to a specific queue. If more than one consumer connects to the same queue, AMQ Broker distributes messages between them.
Figure 4.3. Point-to-Point with Two Queues
This is how AMQ Broker handles load balancing of queues across multiple nodes in a cluster.
Procedure
-
Open the file
BROKER_INSTANCE_DIR/etc/broker.xml
for editing. Wrap an
anycast
configuration element around thequeue
elements in theaddress
.<configuration ...> <core ...> ... <address name="address.foo"> <anycast> <queue name="q1"/> <queue name="q2"/> </anycast> </address> </core> </configuration>
4.5. Using Point-to-Point and Publish-Subscribe Together
It is possible to define an address with both point-to-point and publish-subscribe semantics enabled. While not typically recommended, this can be useful when you want, for example, a JMS Queue named orders
and a JMS topic named orders
. The different routing types make the addresses appear to be distinct.
Using an example of JMS clients, the messages sent by a JMS queue producer are routed using the anycast
routing type. Messages sent by a JMS topic producer uses the multicast
routing type. In addition, when a JMS topic consumer attaches, it is attached to its own subscription queue. The JMS queue consumer, however, is attached to the anycast
queue.
Figure 4.4. Point-to-Point and Publish-Subscribe
The behavior in this scenario is dependent on the protocol being used. For JMS there is a clear distinction between topic and queue producers and consumers, which makes the logic straightforward. Other protocols like AMQP do not make this distinction. A message being sent via AMQP is routed by both anycast
and multicast
and consumers default to anycast
. For more information, check the behavior of each protocol in the sections on protocols.
The XML excerpt below is an example of what the configuration for an address using both anycast
and multicast
routing types would look like in BROKER_INSTANCE_DIR/etc/broker.xml
. Note that subscription queues are typically created on demand, so there is no need to list specific queue
elements inside the multicast
routing type.
<configuration ...> <core ...> ... <address name="foo.orders"> <anycast> <queue name="orders"/> </anycast> <multicast/> </address> </core> </configuration>
4.6. Configuring Subscription Queues
In most cases it is not necessary to pre-create subscription queues because protocol managers create subscription queues automatically when clients first request to subscribe to an address. See Protocol Managers and Addresses for more information. For durable subscriptions, the generated queue name is usually a concatenation of the client id and the address.
Configuring a Durable Subscription Queue
When an queue is configured as a durable subscription, the broker saves messages for any inactive subscribers and delivers them to the subscribers when they reconnect. Clients are therefore guaranteed to receive each message delivered to the queue after subscribing to it.
Procedure
-
Open the file
BROKER_INSTANCE_DIR/etc/broker.xml
for editing. Add the
durable
configuration element to the chosenqueue
and assign it a value oftrue
.<configuration ...> <core ...> ... <address name="durable.foo"> <multicast> <queue name="q1"> <durable>true</durable> </queue> </multicast> </address> </core> </configuration>
Configuring a Non-Shared Durable Subscription
The broker can be configured to prevent more than one consumer from connecting to a queue at any one time. The subscriptions to queues configured this way are therefore "non-shared".
Procedure
-
Open the file
BROKER_INSTANCE_DIR/etc/broker.xml
for editing. Add the
durable
configuration element to each chosen queue.<configuration ...> <core ...> ... <address name="non.shared.durable.foo"> <multicast> <queue name="orders1"> <durable>true</durable> </queue> <queue name="orders2"> <durable>true</durable> </queue> </multicast> </address> </core> </configuration>
Add the
max-consumers
attribute to each chosenqueue
element and assign it a value of1
.<configuration ...> <core ...> ... <address name="non.shared.durable.foo"> <multicast> <queue name="orders1" max-consumers="1"> <durable>true</durable> </queue> <queue name="orders2" max-consumers="1"> <durable>true</durable> </queue> </multicast> </address> </core> </configuration>
4.7. Using a Fully Qualified Queue Name
Internally the broker maps a client’s request for an address to specific queues. The broker decides on behalf of the client which queues to send messages, or from which queue to receive messages. However, more advanced use cases might require that the client specify a queue directly. In these situations the client can use a Fully Qualified Queue Name (FQQN), by specifying both the address name and the queue name, separated by a ::
.
Prerequisites
An address is configured with two or more queues. In the example below the address
foo
has two queues,q1
andq2
.<configuration ...> <core ...> ... <addresses> <address name="foo"> <anycast> <queue name="q1" /> <queue name="q2" /> </anycast> </address> </addresses> </core> </configuration>
Procedure
In the client code, use both the address name and the queue name when requesting a connection from the broker. Remember to use two colons,
::
, to separate the names, as in the example Java code below.String FQQN = "foo::q1"; Queue q1 session.createQueue(FQQN); MessageConsumer consumer = session.createConsumer(q1);
4.8. Configuring Sharded Queues
A common pattern for processing of messages across a queue where only partial ordering is required is to use queue sharding. In AMQ Broker this can be achieved by creating an anycast
address that acts as a single logical queue, but which is backed by many underlying physical queues.
Procedure
Open
BROKER_INSTANCE_DIR/etc/broker.xml
and add anaddress
with the desired name. In the example below theaddress
namedsharded
is added to the configuration.<configuration ...> <core ...> ... <addresses> <address name="sharded"></address> </addresses> </core> </configuration>
Add the
anycast
routing type and include the desired number of sharded queues. In the example below, the queuesq1
,q2
, andq3
are added asanycast
destinations.<configuration ...> <core ...> ... <addresses> <address name="sharded"> <anycast> <queue name="q1" /> <queue name="q2" /> <queue name="q3" /> </anycast> </address> </addresses> </core> </configuration>
Using the configuration above, messages sent to sharded
are distributed equally across q1
, q2
and q3
. Clients are able to connect directly to a specific physical queue when using a fully qualified queue name and receive messages sent to that specific queue only.
To tie particular messages to a particular queue, clients can specify a message group for each message. The broker routes grouped messages to the same queue, and one consumer processes them all. See the chapter on Message Grouping for more information.
4.9. Limiting the Number of Consumers Connected to a Queue
You can limit the number of consumers connected to for a particular queue by using the max-consumers
attribute. Create an exclusive consumer by setting max-consumers
flag can be set to 1
. The default value is -1
, which is sets an unlimited number of consumers.
Procedure
Open
BROKER_INSTANCE_DIR/etc/broker.xml
and add themax-consumers
attribute to the desiredqueue
. In the example below, only20
consumers can connect to the queueq3
at the same time.<configuration ...> <core ...> ... <addresses> <address name="foo"> <anycast> <queue name="q3" max-consumers="20"/> </anycast> </address> </addresses> </core> </configuration>
(Optional) Create an exclusive consumer by setting
max-consumers
to1
, as in the example below.<configuration ...> <core ...> ... <address name="foo"> <anycast> <queue name="q3" max-consumers="1"/> </anycast> </address> </core> </configuration>
(Optional) Have an unlimited number of consumers by setting
max-consumers
to-1
, as in the example below.<configuration ...> <core ...> ... <address name="foo"> <anycast> <queue name="q3" max-consumers="-1"/> </anycast> </address> </core> </configuration>
4.10. Exclusive Queues
Exclusive queues are special queues that route all messages to only one consumer at a time. This is useful when you want all messages to be processed serially by the same consumer. If there are multiple consumers on a queue only one consumer will receive messages. If this consumer disconnects then another consumer is chosen.
4.10.1. Configuring Exclusive Queues
You configure exclusive queues in the broker.xml
configuration file something like this.
<configuration ...> <core ...> ... <address name="foo.bar"> <multicast> <queue name="orders1" exclusive="true"/> </multicast> </address> </core> </configuration>
Or on auto-create when using the JMS Client by using address parameters when creating the destination used by the consumer.
Queue queue = session.createQueue("my.destination.name?exclusive=true"); Topic topic = session.createTopic("my.destination.name?exclusive=true");
4.10.2. Setting the Exclusive Queue Default
<address-setting match="myQueue"> <default-exclusive-queue>true</default-exclusive-queue> </address-setting>
The default value for default-exclusive-queue
is false
.
4.11. Configuring a Prefix to Connect to a Specific Routing Type
Normally, if a message is received by an address that uses both anycast
and multicast
, one of the anycast
queues receive the message and all of the multicast
queues. However, clients can specify a special prefix when connecting to an address to specify whether to connect using anycast
or multicast
. The prefixes are custom values that are designated using the anycastPrefix
and multicastPrefix
parameters within the URL of an acceptor
.
Configuring an Anycast Prefix
-
In
BROKER_INSTANCE_DIR/etc/broker.xml
, add theanycastPrefix
to the URL of the desiredacceptor
. In the example below, theacceptor
is configured to useanycast://
for theanycastPrefix
. Client code can specifyanycast://foo/
if the client needs to send a message to only one of the anycast queues.
<configuration ...> <core ...> ... <acceptors> <!-- Acceptor for every supported protocol --> <acceptor name="artemis">tcp://0.0.0.0:61616?protocols=AMQP;anycastPrefix=anycast://</acceptor> </acceptors> ... </core> </configuration>
Configuring a Multicast Prefix
-
In
BROKER_INSTANCE_DIR/etc/broker.xml
, add theanycastPrefix
to the URL of the desiredacceptor
. In the example below, theacceptor
is configured to usemulticast://
for themulticastPrefix
. Client code can specifymulticast://foo/
if the client needs the message sent to only the multicast queues of the address.
<configuration ...> <core ...> ... <acceptors> <!-- Acceptor for every supported protocol --> <acceptor name="artemis">tcp://0.0.0.0:61616?protocols=AMQP;multicastPrefix=multicast://</acceptor> </acceptors> ... </core> </configuration>
4.12. Protocol Managers and Addresses
A protocol manager maps protocol-specific concepts down to the AMQ Broker address model concepts: queues and routing types. For example, when a client sends a MQTT subscription packet with the addresses /house/room1/lights
and /house/room2/lights
, the MQTT protocol manager understands that the two addresses require multicast
semantics. The protocol manager therefore first looks to ensure that multicast
is enabled for both addresses. If not, it attempts to dynamically create them. If successful, the protocol manager then creates special subscription queues for each subscription requested by the client.
Each protocol behaves slightly differently. The table below describes what typically happens when subscribe frames to various types of queue
are requested.
If the queue is of this type… | The typical action for a protocol manager is to… |
---|---|
Durable Subscription Queue |
Look for the appropriate address and ensures that The special name allows the protocol manager to quickly identify the required client subscription queues should the client disconnect and reconnect at a later date. When the client unsubscribes the queue is deleted. |
Temporary Subscription Queue |
Look for the appropriate address and ensures that When the client disconnects the queue is deleted. |
Point-to-Point Queue |
Look for the appropriate address and ensures that If the queue is auto created, it is automatically deleted once there are no consumers and no messages in it. |
4.13. Disabling Advisory Messages
By default, AMQ creates advisory messages about addresses and queues when an OpenWire client is connected to the broker. Advisory messages are sent to internally managed addresses created by the broker. These addresses appear on the AMQ Console within the same display as user-deployed addresses and queues. Although they provide useful information, advisory messages can cause unwanted consequences when the broker manages a large number of destinations. For example, the messages might increase memory usage or strain connection resources. Also, the AMQ Console might become cluttered when attempting to display all of the addresses created to send advisory messages. To avoid these situations, use the supportAdvisory
and suppressInternalManagementObjects
parameters to manage the advisory messages behavior on the broker side.
-
supportAdvisory: Set this option to
true
to enable creation of advisory messages orfalse
to disable them. The default value istrue
. -
suppressInternalManagementObjects: Set this option to
true
to expose the advisory messages to the management service such as JMX registry and AMQ Console, orfalse
to not expose them. The default value istrue
.
Use these parameters by editing the BROKER_INSTANCE_DIR/etc/broker.xml
configuration file and configure the parameters on openwire acceptors by using URLs. For example:
<acceptor name="artemis">tcp://127.0.0.1:61616?protocols=CORE,AMQP,OPENWIRE;supportAdvisory=false;suppressInternalManagementObjects=false</acceptor>
4.14. Configuring Address Settings
AMQ Broker has several configurable options that control aspects of how and when a message is delivered, how many attempts should be made, and when the message expires. These configuration options all exist within the <address-setting>
configuration element. You can have AMQ Broker apply a single <address-setting>
to multiple destinations by using a wildcard syntax.
AMQ Broker Wildcard Syntax
AMQ Broker uses a specific syntax for representing wildcards in security settings, address settings, and when creating consumers.
- A wildcard expression contains words delimited by the character ‘.’.
- The special characters ‘#’ and ‘*’ also have special meaning and can take the place of a word.
- The character ‘#’ means 'match any sequence of zero or more words'. Use this at the end of your expression.
- The character ‘*’ means 'match a single word'. Use this anywhere within your expression.
Matching is not done character by character, but at each delimiter boundary. For example, an address-setting
looking to match queues using my
in their name would not match with a queue named myqueue
.
When more than one address-setting
matches a queue, the broker will overlay configurations, using the configuration of the least specific match as the baseline. Literal expressions are more specific than wildcards, and *
is more specific than #
. For example, both my.queue
and my.*
match the queue my.queue
. In this case, the broker first applies the configuration found under my.*
, since a wildcard expression is less specific than a literal. Next, the broker overlays the configuration of the my.queue
address-setting
, which will overwrite any configuration shared with my.*
. Given the configuration below, the queue my.queue
would have max-delivery-attempts
set to 3
and last-value-queue
set to false
.
<address-setting match="my.*"> <max-delivery-attempts>3</max-delivery-attempts> <last-value-queue>true</last-value-queue> </address-setting> <address-setting match="my.queue"> <last-value-queue>false</last-value-queue> </address-setting>
The examples in the table below illustrate how wildcards are used to match a set of addresses.
Example | Description |
---|---|
# |
The default |
news.europe.# |
Matches |
news.* |
Matches |
news.*.sport |
Matches |
Configuring Wildcard Syntax
You can customize the syntax used for wildcard addresses by adding configuration to broker.xml
.
Procedure
-
Edit
broker.xml
by adding a<wildcard-addresses>
section to the configuration, as in the example below.
<configuration> <core> ... <wildcard-addresses> 1 <enabled>true</enabled> 2 <delimiter>,</delimiter> 3 <any-words>@</any-words> 4 <single-word>$</single-word> 5 </wildcard-addresses> ... </core> </configuration>
- 1
- Add
wildcard-addresses
beneath thecore
configuration element. - 2
- Set
enabled
totrue
to tell the broker to use your custom settings. - 3
- Provide a custom character to use as the
delimiter
instead of the default, which is.
. - 4
- The character provided as the value for
any-words
is used to mean 'match any sequence of zero or more words' and will replace the default#
. Use this character at the end of your expression. - 5
- The character provided as the value for
single-word
is used to mean 'match a single word' and will replaced the default*
. Use this character anywhere within your expression.
4.15. Creating and Deleting Queues and Addresses Automatically
You can configure AMQ Broker to automatically create addresses and queues, and to delete them after they are no longer in use. This saves you from having to pre-configure each address before a client can connect to it.
Automatic creation and deletion of queues and addresses is configured on a per address-setting
basis. The configuration is applied to any address or queue that is a match for the address-setting
. For more information about how to use wildcard syntax to match addresses and queues to an address-setting
see Configuring Address Settings.
Disabling the automatic creation of queues and addresses can cause problems and is not recommended. AMQ Broker must be able to auto-create addresses and queues by using the activemq.#
pattern. For an example see the example address setting.
The following table lists the configuration elements available when configuring an address-setting
to automatically create and delete its queues and addresses.
If you want the address-setting to… | Add this configuration… |
---|---|
Create addresses when a client sends a message to or attempts to consume a message from a queue mapped to an address that does not exist. |
|
Create a queue when a client sends a message to or attempts to consume a message from a queue. |
|
Delete an automatically created address when it no longer has any queues. |
|
Delete an automatically created queue when the queue has 0 consumers and 0 messages. |
|
Use a specific routing type if the client does not specify one. |
|
Procedure
Edit the BROKER_INSTANCE_DIR/etc/broker.xml
file and configure an address-setting
for automatic creation and deletion. The following example uses all of the configuration elements mentioned in the previous table.
<configuration ...> <core ...> ... <address-settings> <address-setting match="activemq.#"> 1 <auto-create-addresses>true</auto-create-addresses> 2 <auto-delete-addresses>true</auto-delete-addresses> 3 <auto-create-queues>true</auto-create-queues> 4 <auto-delete-queues>true</auto-delete-queues> 5 <default-address-routing-type>ANYCAST</default-address-routing-type> 6 </address-setting> </address-settings> ... </core> </configuration>
- 1
- The configuration included in this
address-setting
is applied to any address or queue that matches the wildcardactivemq.#
. For more information on using wildcard syntax see AMQ Broker Wildcard Syntax. - 2
- The broker creates an address that does not exist when a client requests it.
- 3
- An automatically created address is deleted when it no longer has any queues associated with it.
- 4
- The broker creates a queue that does not exist when a client requests it.
- 5
- An automatically created queue is deleted when it no longer has any consumers or messages.
- 6
- If the client does not specify a routing type when connecting, the broker uses
ANYCAST
when delivering messages to an address. The default value isMULTICAST
. See the introduction of this chapter for more information about routing types.