Chapter 2. Network Connectors

Abstract

The network connector is the glue that binds a network of brokers. They are define the pathways between the brokers and are responsible for controlling how messages propagate throughout the network.

Overview

Network connectors define the broker-to-broker links that are the basis of a broker network. This section defines the basic options for configuring network connectors and explains the concepts that underlie them.

Active consumers

An active consumer is a consumer that is connected to one of the brokers in the network, has indicated to the broker which topics and queues it wants to receive messages on, and is ready to receive messages. The broker network has the ability to keep track of active consumers, receiving notifications whenever a consumer connects to or disconnects from the network.

Subscriptions

In the context of a broker network, a subscription is a block of data that represents an active consumer's interest in receiving messages on a particular queue or on a particular topic. Brokers use the subscription data to decide what messages to send where. Subscriptions, therefore, encapsulate all of the information that a broker might need to route messages to a consumer, including JMS selectors and which route to take through the broker network.
Subscriptions are inherently dynamic. If a given consumer disconnects from the broker network (thus becoming inactive), its associated subscriptions are automatically cancelled throughout the network.
Note
This usage of the term, subscription, deviates from standard JMS terminology, where there can be topic subscriptions but there is no such thing as a queue subscription. In the context of broker networks, however, we speak of both topic subscriptions and queue subscriptions.

Propagation of subscriptions

Both topic subscriptions and queue subscriptions propagate automatically through a broker network. That is, when a consumer connects to a broker, it passes its subscriptions to the local broker and the local broker then forwards the subscriptions to neighbouring brokers. This process continues until the subscriptions are propagated throughout the broker network.
Under the hood, Red Hat JBoss A-MQ implements subscription propagation using advisory messages, where an advisory message is a message sent through one of the special channels known as an advisory topic. An advisory topic is essentially a reserved JMS topic used for transmitting administrative messages. All advisory topics have names that start with the prefix, ActiveMQ.Advisory.
Warning
In order for dynamic broker networks to function correctly, it is essential that advisory messages are enabled (which they are by default). Make sure that you do not disable advisory messages on any broker in the network. For example, if you are configuring your brokers using XML, make sure that the advisorySupport attribute on the broker element is not set to false.
In principle, it is possible to configure a static broker network when advisory messages are disabled. See Chapter 3, Dynamic and Static Propagation for details.

Network connector

A broker network is built up by defining directed connections from one broker to another, using network connectors. The broker that establishes the connection passes messages to the broker it is connected to. In XML, a network connector is defined using the networkConnector element, which is a child of the networkConnectors element.

Single connector

Figure 2.1, “Single Connector” shows a single network connector from broker A to broker B. The arrow on the connector indicates the direction of message propagation (from A to B). Subscriptions propagate in the opposite direction (from B to A). Because of the restriction on the direction of message flow in this network, it is advisable to connect producers only to broker A and consumers only to broker B. Otherwise, some messages might not be able to reach the intended consumers.

Figure 2.1. Single Connector

Single Connector
When the connector arrow points from A to B, this implies that the network connector is actually defined on broker A. For example, the following fragment from broker A's configuration file shows the network connector that connects to broker B:

Example 2.1. Single connector configuration

<beans ...>
    <broker xmlns="http://activemq.apache.org/schema/core"
            brokerName="brokerA" brokerId="A" ... >
        ...
        <networkConnectors>
            <networkConnector name="linkToBrokerB"
                uri="static:(tcp://localhost:61002)"
                networkTTL="3"
            />            
        </networkConnectors>
        ...
        <transportConnectors>
            <transportConnector name="openwire" uri="tcp://0.0.0.0:61001"/>
        </transportConnectors>
    </broker>
</beans>
The networkConnector element in the preceding example sets the following basic attributes:
name
Identifies this network connector instance uniquely (for example, when monitoring the broker through JMX). If you define more than one networkConnector element on a broker, you must set the name in order to ensure that the connector name is unique within the scope of the broker.
uri
The discovery agent URI that returns which brokers to connect to. In other words, broker A connects to every transport URI returned by the discovery agent.
In the preceding example, the static discovery agent URI returns a single transport URI, tcp://localhost:61002, which refers to a port opened by one of the transport connectors on broker B.
networkTTL
The network time-to-live (networkTTL) attribute specifies the maximum number of hops that a message can make through the broker network. It is almost always necessary to set this attribute because the default value (1) enables a message to make just one hop to a neighboring broker.
Each time a message is forwarded across a network bridge, the receiving broker's ID is appended to an internal BrokerId array, BrokerPath. Comparison of the networkTTL's setting with the size of BrokerPath enforces the configured number of hops.
When messages fail to propagate as expected, you can use BrokerPath, which is exposed as a string property, to check the brokers that specific messages have traversed. Two methods are available, and both return a comma-separated list of broker IDs:
  • Browsing a message via JConsole, hawtio, or a JMS browser to check its BrokerPath property
  • Programmatically via getStringProperty("JMSActiveMQBrokerPath"); for example:
    ((ActiveMQMessage)message1).getStringProperty(ActiveMQMessage.BROKER_PATH_PROPERTY).
                contains(localBroker.getBroker().getBrokerId().toString())
A list of returned broker IDs looks something like this:
[ID:jdoe-ThinkPad-T222s-35488-1985672254433-0:2,
                            id_broker3, id_broker2]
In this example, the first ID, jdoe-ThinkPad-T222s-35488-1985672254433-0:2, is an embedded broker that has an automatically generated ID based on machine-name, and the second and third brokers were manually created with configured IDs.

Connectors in each direction

Figure 2.1, “Single Connector” shows a pair of network connectors in each direction: one from broker A to broker B, and one from broker B to broker A. In this network, there is no restriction on the direction of message flow and messages can propagate freely in either direction. It follows that producers and consumers can arbitrarily connect to either broker in this network.

Figure 2.2. Connectors in Each Direction

Connectors in Each Direction
In order to create a connector in the reverse direction, from B to A, define a network connector on broker B, as follows:

Example 2.2. Two way connector

<beans ...>
    <broker xmlns="http://activemq.apache.org/schema/core"
            brokerName="brokerB" brokerId="B"... >
        ...
        <networkConnectors>
            <networkConnector name="linkToBrokerA"
                uri="static:(tcp://localhost:61001)"
                networkTTL="3" />            
        </networkConnectors>
        ...
        <transportConnectors>
            <transportConnector name="openwire" uri="tcp://0.0.0.0:61002" />
        </transportConnectors>
    </broker>
</beans>

Duplex connector

An easier way to enable message propagation in both directions is by enabling duplex mode on an existing connector. Figure 2.3, “Duplex Connector” shows a duplex network connector defined on broker A (where the dot indicates which broker defines the network connector in the figure). The duplex connector allows messages to propagate in both directions, but only one network connector needs to be defined and only one network connection is created.

Figure 2.3. Duplex Connector

Duplex Connector
To enable duplex mode on a network connector, simple set the duplex attibute to true. For example, to make the network connector on broker A a duplex connector, you can configure it as follows:

Example 2.3. Duplex connector configuration

<networkConnectors>
   <networkConnector name="linkToBrokerB"
       uri="static:(tcp://localhost:61002)"
       networkTTL="3"
       duplex="true" />
</networkConnectors>
Note
Duplex mode is particularly useful for cases where a network connection must be established across a firewall, because only one port need be opened on the firewall to enable bi-directional traffic.
Note
Duplex mode works particularly well in a hub and spoke network. The spokes only need to know about one hub port and the hub does not need to know any of the spoke addresses (each spoke opens a duplex network connector to the hub).

Multiple connectors

It is also possible to establish multiple connectors between brokers, as long as you observe the rule that each connector has a unique name. Figure 2.4, “Multiple Connectors” shows an example where three network connectors are established from broker A to broker B.

Figure 2.4. Multiple Connectors

Multiple Connectors
To configure multiple connectors from broker A, use a separate networkConnector element for each connector and specify a unique name for each connector, as follows:
<networkConnectors>
   <networkConnector name="link01ToBrokerB"
       uri="static:(tcp://localhost:61002)"
       networkTTL="3"
   />
   <networkConnector name="link02ToBrokerB"
       uri="static:(tcp://localhost:61002)"
       networkTTL="3"
   />
   <networkConnector name="link03ToBrokerB"
       uri="static:(tcp://localhost:61002)"
       networkTTL="3"
   />
</networkConnectors>
Here are some potential uses for creating multiple connectors between brokers:
  • Spreading the load amongst multiple connections.
  • Defining separate configuration for topics and queues. That is, you can configure one network connector to transmit queue subscriptions only and another network connector to transmit topic subscriptions only.

Conduit subscriptions

By default, after passing through a network connector, subscriptions to the same queue or subscriptions to the same topic are automatically consolidated into a single subscription known as a conduit subscription. Figure 2.5, “Conduit Subscriptions” shows an overview of how the topic subscriptions from two consumers, C1 and C2, are consolidated into a single conduit subscription after propagating from broker B to broker A.

Figure 2.5. Conduit Subscriptions

Conduit Subscriptions
In this example, each consumer subscribes to the identical topic, t, which gives rise to the subscriptions, C1:t and C2:t in broker B. Both of these subscriptions propagate automatically from broker B to broker A. Because broker A has conduit subscriptions enabled, its network connector consolidates the duplicate subscriptions, C1:t and C2:t, into a single subscription, B:t. Now, if a message on topic t is sent to broker A, broker A sends a single copy of the message to broker B, to honor the conduit subscription, B:t. Broker B then sends a copy of the message to each consumer, to honor the topic subscriptions, C1:t and C2:t.
It is essential to enable conduit subscription in order to avoid duplication of topic messages. Consider what would happen in Figure 2.5, “Conduit Subscriptions” if conduit subscription was disabled. In this scenario, two subscriptions, B:C1:t and B:C2:t, would be registered in broker A. Now, if a message on topic t is sent to broker A, broker A would send two copies of the message to broker B, to honor the topic subscriptions, B:C1:t and B:C2:t. Broker B would then send two copies of the message to each consumer, to honor the topic subscriptions, C1:t and C2:t. In other words, each consumer would receive the topic message twice.
Conduit subscriptions can optionally be disabled by setting the conduitSubscriptions attribute to false on the networkConnector element. See Section 9.1, “Balancing Consumer Load” for more details.