blob: 52e4b19c021a029671e6eed1d88af4a2186ab4f8 [file] [log] [blame]
.. Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
Indirect Waypoints and Auto-Links
=================================
This feature was introduced in Qpid Dispatch 0.6. It is a significant
improvement on an earlier somewhat experimental feature called
Waypoints.
Auto-link is a feature of Qpid Dispatch Router that enables a router
to actively attach a link to a node on an external AMQP container.
The obvious application for this feature is to route messages through
a queue on a broker, but other applications are possible as well.
An auto-link manages the lifecycle of one AMQP link. If messages are
to be routed to and from a queue on a broker, then two auto-links are
needed: one for sending messages to the queue and another for
receiving messages from the queue. The container to which an
auto-link attempts to attach may be identified in one of two ways:
- The name of the connector/listener that resulted in the connection
of the container, or
- The AMQP container-id of the remote container.
Queue Waypoint Example
----------------------
Here is an example configuration for routing messages deliveries
through a pair of queues on a broker:
::
connector {
name: broker
role: route-container
addr: <hostname>
port: <port>
sasl-mechanisms: ANONYMOUS
}
address {
prefix: queue
waypoint: yes
}
autoLink {
addr: queue.first
dir: in
connection: broker
}
autoLink {
addr: queue.first
dir: out
connection: broker
}
autoLink {
addr: queue.second
dir: in
connection: broker
}
autoLink {
addr: queue.second
dir: out
connection: broker
}
The *address* entity identifies a namespace (queue.*) that will be
used for routing messages through queues via autolinks. The four
*autoLink* entities identify the head and tail of two queues on the
broker that will be connected via auto-links.
If there is no broker connected, the auto-links shall remain
*inactive*. This can be observed by using the *qdstat* tool:
::
$ qdstat --autolinks
AutoLinks
addr dir phase link status lastErr
===================================================
queue.first in 1 inactive
queue.first out 0 inactive
queue.second in 1 inactive
queue.second out 0 inactive
If a broker comes online with a queue called *queue.first*, the
auto-links will attempt to activate:
::
$ qdstat --autolinks
AutoLinks
addr dir phase link status lastErr
======================================================================
queue.first in 1 6 active
queue.first out 0 7 active
queue.second in 1 failed Node not found: queue.second
queue.second out 0 failed Node not found: queue.second
Note that two of the auto-links are in *failed* state because the
queue does not exist on the broker.
If we now use the Qpid Proton example application *simple_send* to
send three messages to queue.first via the router:
::
$ python simple_send.py -a 127.0.0.1/queue.first -m3
all messages confirmed
and then look at the address statistics on the router:
::
$ qdstat -a
Router Addresses
class addr phs distrib in-proc local remote cntnr in out thru to-proc from-proc
========================================================================================================
mobile queue.first 1 balanced 0 0 0 0 0 0 0 0 0
mobile queue.first 0 balanced 0 1 0 0 3 3 0 0 0
we see that *queue.first* appears twice in the list of addresses. The
*phs*, or phase column shows that there are two phases for the
address. Phase '0' is for routing message deliveries from producers
to the tail of the queue (the *out* auto-link associated with the
queue). Phase '1' is for routing deliveries from the head of the
queue to subscribed consumers.
Note that three deliveries have been counted in the "in" and "out"
columns for phase '0'. The "in" column represents the three messages
that arrived from simple_send and the "out" column represents the
three deliveries to the queue on the broker.
If we now use *simple_recv* to receive three messages from this
address:
::
$ python simple_recv_noignore.py -a 127.0.0.1:5672/queue.first -m3
{u'sequence': int32(1)}
{u'sequence': int32(2)}
{u'sequence': int32(3)}
We receive the three queued messages. Looking at the addresses again,
we see that phase '1' was used to deliver those messages from the
queue to the consumer.
::
$ qdstat -a
Router Addresses
class addr phs distrib in-proc local remote cntnr in out thru to-proc from-proc
========================================================================================================
mobile queue.first 1 balanced 0 0 0 0 3 3 0 0 0
mobile queue.first 0 balanced 0 1 0 0 3 3 0 0 0
Note that even in a multi-router network, and with multiple producers
and consumers for *queue.first*, all deliveries will be routed through
the queue on the connected broker.
Sharded Queue Example
---------------------
Here is an extension of the above example to illustrate how Qpid
Dispatch Router can be used to create a distributed queue in which
multiple brokers share the message-queueing load.
::
connector {
name: broker1
role: route-container
addr: <hostname>
port: <port>
sasl-mechanisms: ANONYMOUS
}
connector {
name: broker2
role: route-container
addr: <hostname>
port: <port>
sasl-mechanisms: ANONYMOUS
}
address {
prefix: queue
waypoint: yes
}
autoLink {
addr: queue.first
dir: in
connection: broker1
}
autoLink {
addr: queue.first
dir: out
connection: broker1
}
autoLink {
addr: queue.first
dir: in
connection: broker2
}
autoLink {
addr: queue.first
dir: out
connection: broker2
}
In the above configuration, there are two instances of *queue.first*
on brokers 1 and 2. Message traffic from producers to address
*queue.first* shall be balanced between the two instance and messages
from the queues shall be balanced across the collection of subscribers
to the same address.
Dynamically Adding Shards
-------------------------
Since configurable entities in the router can also be accessed via the
management protocol, we can remotely add a shard to the above example
using *qdmanage*:
::
qdmanage create --type org.apache.qpid.dispatch.connector addr=<host> port=<port> name=broker3
qdmanage create --type org.apache.qpid.dispatch.router.config.autoLink addr=queue.first dir=in connection=broker3
qdmanage create --type org.apache.qpid.dispatch.router.config.autoLink addr=queue.first dir=out connection=broker3