Version 4.4.1
Copyright © 2011-2013 Red Hat, Inc. and/or its affiliates.
Table of Contents
List of Figures
List of Tables
List of Examples
Fuse Message Broker supports a wide variety of protocols for client-to-broker, broker-to-broker, and client-to-client connections. The intention is that the variety of protocols will make it easier to connect to a range of client types. Different network topologies can also be supported with the help of special protocols, such as discovery and peer-to-peer.
The following protocols can be used either for straightforward client-to-broker connections (transport connector) or broker-to-broker connections (network connector). For each wire protocol (that is, on-the-wire message encoding), Fuse Message Broker supports one or more associated transport protocols. Hence, you can configure connections with a wide variety of wire protocol/transport protocol combinations.
Table 1.1 shows the protocol combinations that messaging clients can use to connect directly to the message broker.
Table 1.1. Protocols for Simple Connections
| Wire Protocol | Transport Protocol | Sample URL | Description |
|---|---|---|---|
| OpenWire | TCP | tcp:// |
Connect to the message broker endpoint at
This URL is also used to configure the transport connector in a broker. |
| OpenWire | TCP | nio:// | Same as tcp, except that the New I/O (NIO) Java API is
used, which provides better performance in some scenarios. |
| OpenWire | SSL | ssl:// |
Connect to the message broker endpoint at
This URL is also used to configure the transport connector in a broker. |
| OpenWire | HTTP | http:// |
Connect to the message broker endpoint at
This URL is also used to configure the transport connector in a broker. |
| OpenWire | HTTPS | https://Host:Port |
Connect to the message broker endpoint at
This URL is also used to configure the transport connector in a broker. |
| Stomp | TCP | stomp://Host:Port |
Connect to the message broker endpoint at
This URL is also used to configure the transport connector in a broker. |
| Stomp | SSL | stomp+ssl://Host:Port |
Connect to the message broker endpoint at
This URL is also used to configure the transport connector in a broker. |
| REST | HTTP | http:// |
Connect to the message broker endpoint at
For example, the sample URL is built up from a Web context name,
This URL is not used to configure the REST transport
connector in a broker. Use the |
| RESTs | HTTPS | http:// | |
| XMPP | TCP | xmpp://Host:Port | Configure the transport connector in a message broker to accept XMPP
connections on
Host:Port
(for example, from an Instant Messaging client). |
| VM | N/A | vm://BrokerName | Configure clients to connect to a broker embedded within the same Java Virtual
Machine (JVM). The BrokerName is the broker name of the
embedded broker. |
A discovery protocol builds a connection to a message broker in two steps, as follows:
Obtain a list of available broker endpoints (represented by URIs).
Connect to one or more endpoints from the discovered list, according to some selection algorithm.
Discovery protocols are particularly useful for clients that connect to a cluster of message brokers.
Table 1.2 describes the discovery protocols that clients can use.
Table 1.2. Summary of Discovery Protocols
| Protocol | Sample URL | Description |
|---|---|---|
| Failover | failover://(uri1,...,uriN)?TransportOptions | Configure clients to connect to one of the broker endpoints from the URI list,
uri1,...,uriN.
The transport options,
?TransportOptions, are specified in
the form of a query list. If no transport options are required, you can omit the
parentheses and the question mark, ?. |
| Discovery | discovery://(DiscoveryAgentUri)?TransportOptions | Configure clients to connect to one of the broker endpoints from a URI list
that is dynamically discovered at runtime, using a discovery agent. The discovery
agent URI, DiscoveryAgentUri, is normally a multicast
discovery agent—for example, multicast://default. |
| Fanout | fanout://(DiscoveryAgentUri)?TransportOptions | Configure clients to connect to all of the broker endpoints from a dynamically discovered URI list. |
The discovery protocol supports a number of discovery agents, which are also specified in the form of a URI. For details of the supported discovery agents, see Discovery Agents .
Although discovery agent URIs look superficially like transport URIs, they are not the same thing. A discovery agent URI can only be used in certain contexts and cannot be used directly in place of a transport URI.
The OpenWire protocol is the default on-the-wire protocol for Fuse Message Broker. This chapter provides a brief introduction to the protocol, illustrating how to use OpenWire with a variety of transport protocols.
The OpenWire protocol is a JMS compliant wire protocol (defining message types and message encodings) that is native to the Fuse Message Broker. The protocol is designed to be fully-featured, JMS-compliant, and highly performant. It is the default protocol of the Fuse Message Broker.
Table 2.1 shows the transport protocols supported by the OpenWire wire protocol:
Table 2.1. Transport Protocols Supported by OpenWire
| Transport Protocol | URL | Description |
|---|---|---|
| TCP | tcp:// |
Endpoint URL for OpenWire over TCP/IP. The broker
listens for TCP connections on the host machine,
|
| TCP | nio:// | Same as tcp, except that the New I/O
(NIO) Java API is used, which provides better
performance in some scenarios. |
| SSL | ssl:// |
(Java clients only) Endpoint URL for OpenWire over TCP/IP, where the socket layer is secured using SSL (or TLS). For details of how to configure an SSL connection, see ActiveMQ Security Guide. |
| HTTP | http:// |
(Java clients only) Endpoint URL for OpenWire over HTTP. |
| HTTPS | https:// |
(Java clients only) Endpoint URL for OpenWire over HTTP, where the socket layer is secured by SSL (or TLS). For details of how to configure a HTTPS connection, see ActiveMQ Security Guide. |
OpenWire supports a number of transport options, which can be set as query options on the transport URL. For example, to specify that error messages should omit the stack trace, use a URL like the following:
tcp://localhost:61616?wireformat.stackTraceEnabled=false
Where the wireformat.stackTraceEnabled property is set to
false to disable the inclusion of stack traces in error messages.
Table 2.2 gives the complete list of transport options for
OpenWire.
Table 2.2. Transport Options Supported by OpenWire Protocol
| Property | Default | Description | Negotiation policy |
|---|---|---|---|
wireformat
.stackTraceEnabled | true |
Should the stack trace of an exception occuring on the broker be sent to the client? |
Set to |
wireformat
.tcpNoDelayEnabled | false |
Provides a hint to the peer that TCP
|
Set to |
wireformat
.cacheEnabled | true |
Should commonly repeated values be cached so that less marshalling occurs? |
Set to |
wireformat
.cacheSize | 1024 |
If |
Use the smaller of the two values. |
wireformat
.tightEncodingEnabled | true |
Should wire size be optimized over CPU usage? |
Set to |
wireformat
.prefixPacketSize | true |
Should the size of the packet be prefixed before each packet is marshalled? |
Set to |
wireformat
.maxInactivityDuration | 30000 |
The maximum inactivity duration (before which the
socket is considered dead) in milliseconds. On some
platforms it can take a long time for a socket to
appear to die, so we allow the broker to kill
connections if they are inactive for a period of time.
Set to a value |
Use the smaller of the two values. |
wireformat
.maxInactivityDurationInitalDelay |
Fuse Message Broker currently supports the following client types for the OpenWire protocol:
Java clients—the Java API conforms fully to the JMS specification.
If you want to develop an OpenWire client using other programming languages, try one of the following client types from the Apache ActiveMQ project:
C++ clients—for C++ clients, Apache ActiveMQ provides the CMS (C++ Messaging Service) API, which is closely modelled on the JMS specification. Only the TCP transport is supported for C++ clients.
The demonstration code required to run these examples is available only from the standalone Apache ActiveMQ package, which you must download and install in addition to Fuse ESB.
It is relatively straightforward to try out the various OpenWire+transport combinations using the sample code provided. After configuring the broker with the requisite transport connectors, you can use the sample producer tool and the consumer tool to propagate messages through the broker using the following protocols: OpenWire over TCP or OpenWire over HTTP.
The secure socket protocols—OpenWire over SSL, and OpenWire over HTTPS—are discussed in ActiveMQ Security Guide.
To run these examples, you require:
Apache Ant build tool, version 1.6 or later.
Standalone Fuse Message Broker package, available from fusesource.com. It is assumed that you install this
package to the directory,
ActiveMQInstallDir.
The OpenWire examples depend on the sample producer and consumer clients located in the following directory:
ActiveMQInstallDir/fuse-message-broker-Version/example
To try out the OpenWire protocol, perform the following steps:
For full details of how to deploy a broker in the OSGi
container, please read Deploying a JMS Broker in Deploying into the OSGi Container. If you have not already deployed a broker, you
can create and deploy a new broker, broker1, by entering the
following console command:
karaf@root> activemq:create-broker --name broker1
Add a HTTP transport connector by editing the broker configuration file (in
)
as follows:InstallDir/deploy/broker1-broker.xml
<beans>
...
<transportConnectors>
...
<transportConnector name="openwire" uri="tcp://localhost:61616"/>
<transportConnector name="http" uri="http://localhost:61620"/>
</transportConnectors>
...
</beans>To connect the consumer tool to the tcp://localhost:61616
endpoint (OpenWire over TCP), change directory to
ActiveMQInstallDir/example
and enter the following command:
ant consumer -Durl=tcp://localhost:61616 -Dmax=100
You should see some output like the following:
Buildfile: build.xml
init:
compile:
consumer:
[echo] Running consumer against server at $url = tcp://localhost:61616
for subject $subject = TEST.FOO
[java] Connecting to URL: tcp://localhost:61616
[java] Consuming queue: TEST.FOO
[java] Using a non-durable subscription
[java] We are about to wait until we consume: 100 message(s) then
we will shutdownTo connect the producer tool to the tcp://localhost:61616
endpoint (OpenWire over TCP), open a new command prompt, change directory to
ActiveMQInstallDir/example
and enter the following command:
ant producer -Durl=tcp://localhost:61616
In the window where the consumer tool is running, you should see some output like the following:
[java] Received: Message: 0 sent at: Wed Sep 19 14:38:06 BST
2007 ...
[java] Received: Message: 1 sent at: Wed Sep 19 14:38:06 BST
2007 ...
[java] Received: Message: 2 sent at: Wed Sep 19 14:38:06 BST
2007 ...
[java] Received: Message: 3 sent at: Wed Sep 19 14:38:06 BST
2007 ...
[java] Received: Message: 4 sent at: Wed Sep 19 14:38:06 BST
2007 ...
[java] Received: Message: 5 sent at: Wed Sep 19 14:38:06 BST
2007 ...
[java] Received: Message: 6 sent at: Wed Sep 19 14:38:06 BST
2007 ...
[java] Received: Message: 7 sent at: Wed Sep 19 14:38:06 BST
2007 ...
[java] Received: Message: 8 sent at: Wed Sep 19 14:38:06 BST
2007 ...
[java] Received: Message: 9 sent at: Wed Sep 19 14:38:06 BST
2007 ...To connect the producer tool to the http://localhost:61620
endpoint (OpenWire over HTTP), enter the following command from the
example directory:
ant producer -Durl=http://localhost:61620
This command sends ten new messages to the consumer client.
The JAR files for the HTTP protocol are currently located in the
lib/optional subdirectory. If you construct the
CLASSPATH manually, you must be sure to include the JAR files from this
subdirectory.
The Stomp protocol is a simplified messaging protocol that is specially designed for implementing clients using scripting languages. This chapter provides a brief introduction to the protocol.
The Stomp protocol is a simplified messaging protocol that is being developed as an open source project (http://stomp.codehaus.org/). The advantage of the stomp protocol is that you can easily improvise a messaging client—even when a specific client API is not available—because the protocol is so simple.
Table 3.1 shows the transport protocols supported by the Stomp wire protocol:
Table 3.1. Transport Protocols Supported by Stomp
| Transport Protocol | URL | Description |
|---|---|---|
| TCP | stomp:// |
Endpoint URL for Stomp over TCP/IP. The broker listens for TCP connections on the host
machine, |
| SSL | stomp+ssl://Host:Port |
Endpoint URL for secure Stomp over SSL. The broker listens for TCP connections on the
host machine, |
This section describes the format of Stomp data packets , as well as the semantics of the
data packet exchanges. Stomp is a relatively simple wire protocol—it is even possible to
communicate manually with a Stomp broker using a telnet client (see Stomp Tutorial ).
In principal, Stomp can be combined with any transport protocol, including connection-oriented and non-connection-oriented transports. In practice, though, Stomp is usually implemented over TCP and this is the only transport currently supported by Fuse Message Broker.
The Stomp specification is licensed under the Creative Commons Attribution v2.5
The Stomp specification defines the term frame to refer to the data packets transmitted over a Stomp connection. A Stomp frame has the following general format:
<StompCommand>
<HeaderName_1>:<HeaderValue_1>
<HeaderName_2>:<HeaderValue_2>
<FrameBody>
^@A Stomp frame always starts with a Stomp command (for example, SEND) on
a line by itself. The Stomp command may then be followed by zero or more header lines: each
header is in a <key>:<value> format and terminated by a newline.
A blank line indicates the end of the headers and the beginning of the body,
<FrameBody>, (which is empty for many of the commands). The frame is
terminated by the null character, which is represented as ^@ above (Ctrl-@ in
ASCII)).
Most Stomp commands have oneway semantics (that is, after sending a frame, the sender does not expect any reply). The only exceptions are:
CONNECT command—after a client sends a
CONNECT frame, it expects the server to reply with a
CONNECTED frame.
Commands with a receipt
header—a client can force the server to acknowledge receipt of a command by adding
a receipt header to the outgoing frame.
Erroneous commands—if a client sends a frame that is malformed, or
otherwise in error, the server may reply with an ERROR frame. Note,
however, that the ERROR frame is not formally correlated with the original
frame that caused the error (Stomp frames are not required to include a unique
identifier).
Any client frame, other than CONNECT, may specify a
receipt header with an arbitrary value. This causes the server to
acknowledge receipt of the frame with a RECEIPT frame, which contains the
value of this header as the value of the receipt-id header in the
RECEIPT frame. For example, the following frame shows a
SEND command that includes a receipt header:
SEND destination:/queue/a receipt:message-12345 Hello a!^@
Table 3.2 lists the client commands for the Stomp protocol. The Reply column indicates whether or not the server sends a reply frame by default.
Table 3.2. Client Commands for the Stomp Protocol
| Command | Reply? | Role | Description |
|---|---|---|---|
| CONNECT | Yes | Producer, Consumer | Open a connection to a Stomp broker (server). |
| SEND | No | Producer | Send a message to a particular queue or topic on the server. |
| SUBSCRIBE | No | Consumer | Subscribe to a particular queue or topic on the server. |
| UNSUBSCRIBE | No | Consumer | Cancel a subscription to a particular queue or topic. |
| ACK | No | Consumer | Acknowledge receipt of one message. |
| BEGIN | No | Producer, Consumer | Start a transaction (applies to SEND or ACK
commands). |
| COMMIT | No | Producer, Consumer | Commit a transaction. |
| ABORT | No | Producer, Consumer | Roll back a transaction. |
| DISCONNECT | No | Producer, Consumer | Shut down the existing connection gracefully. |
After opening a socket to connect to the remote server, the client sends a
CONNECT command to initiate a Stomp session. For example, the following
frame shows a typical CONNECT command, including a login
header and a passcode header:
CONNECT login: <username> passcode:<passcode> ^@
After the client sends the CONNECT frame, the server always acknowledges
the connection by sending a frame, as follows:
CONNECTED session: <session-id> ^@
The session-id header is a unique identifier for this session (currently
unused).
The SEND command sends a message to a
destination—for example, a queue or a topic—in the messaging system. It
has one required header, destination, which indicates where to send the
message. The body of the SEND command is the message to be sent. For example,
the following frame sends a message to the /queue/a destination:
SEND destination:/queue/a hello queue a ^@
From the client’s perspective, the destination name, /queue/a, is an
arbitrary string. Despite seeming to indicate that the destination is a queue it does not, in
fact, specify any such thing. Destination names are simply strings that are mapped to some form
of destination on the server; how the server translates these strings is up to the
implementation.
The SEND command also supports the following optional headers:
transaction—specifies the transaction ID. Include this header, if the
SEND command partakes in a transaction (see BEGIN
).
content-length—specifies the byte count for the length of the message
body. If a content-length header is included, this number of bytes should
be read, regardless of whether or not there are null characters in the body. The frame still
needs to be terminated with a null byte and if a content-length is not specified, the first
null byte encountered signals the end of the frame.
The SUBSCRIBE command registers a client’s interest in listening to a
specific destination. Like the SEND command, the SUBSCRIBE
command requires a destination header. Henceforth, any messages received on
the subscription are delivered as MESSAGE frames, from the server to the
client. For example, the following frame shows a client subscribing to the destination,
/queue/a:
SUBSCRIBE destination: /queue/foo ack: client ^@
In this case the ack header is set to client, which
means that messages are considered delivered only after the client specifically acknowledges
them with an ACK frame. The body of the SUBSCRIBE command
is ignored.
The SUBSCRIBE command supports the following optional headers:
ack—specify the acknowledgement mode for this subscription. The
following modes are recognized:
auto—messages are considered delivered as soon as the server
delivers them to the client (in the form of a MESSAGE command). The
server does not expect to receive any ACK commands
from the client for this subscription.
client—messages are considered delivered only after the client
specifically acknowledges them with an ACK frame.
selector—specifies a SQL 92 selector on the message headers, which
acts as a filter for content based routing.
id—specify an ID to identify this subscription. Later, you can use the
ID to UNSUBSCRIBE from this subscription (you may end up with overlapping
subscriptions, if multiple selectors match the same destination).
When an id header is supplied, the server should append a
subscription header to any MESSAGE commands sent to the
client. When using wildcards and selectors, this enables clients to figure out which
subscription triggered the message.
The UNSUBSCRIBE command removes an existing subscription, so that the
client no longer receives messages from that destination. It requires either a
destination header or an id header (if the previous
SUBSCRIBE operation passed an id value). For example, the
following frame cancels the subscription to the /queue/a destination:
UNSUBSCRIBE destination: /queue/a ^@
The ACK command acknowledges the consumption of a message from a
subscription. If the client issued a SUBSCRIBE frame with an
ack header set to client, any messages received from that
destination are not considered to have been consumed until the message is acknowledged by an
ACK frame.
The ACK command has one required header, message-id,
which must contain a value matching the message-id for the
MESSAGE being acknowledged. Optionally, a transaction
header may be included, if the acknowledgment participates in a transaction. For example, the
following frame acknowledges a message in the context of a transaction:
ACK message-id: <message-identifier> transaction: <transaction-identifier> ^@
The BEGIN command initiates a transaction. Transactions can be applied
to SEND and ACK commands. Any messages sent or
acknowledged during a transaction can either be commited or rolled back at the end of the
transaction.
BEGIN transaction: <transaction-identifier> ^@
The transaction header is required and the
<transaction-identifier> can be included in SEND,
COMMIT, ABORT, and ACK frames to bind
them to the named transaction.
The COMMIT command commits a specific transaction.
COMMIT transaction: <transaction-identifier> ^@
The transaction header is required and specifies the transaction,
<transaction-identifier>, to commit.
The ABORT command rolls back a specific transaction.
ABORT transaction: <transaction-identifier> ^@
The transaction header is required and specifies the transaction,
<transaction-identifier>, to roll back.
Table 3.3 lists the commands that the server can send to a Stomp client. These commands all have oneway semantics.
Table 3.3. Server Commands for the Stomp Protocol
| Command | Description |
|---|---|
| MESSAGE | Send a message to the client, where the client has previously registered a subscription with the server. |
| RECEIPT | Acknowledges receipt of a client command, if the client requested a receipt by
included a receipt-id header. |
| ERROR | Error message sent from the server to the client. |
The MESSAGE command conveys messages from a subscription to the client.
The MESSAGE frame must include a destination header, which
identifies the destination from which the message is taken. The MESSAGE frame
also contains a message-id header with a unique message identifier. The frame
body contains the message contents. For example, the following frame shows a typical
MESSAGE command with destination and
message-id headers:
MESSAGE destination:/queue/a message-id: <message-identifier> hello queue a^@
The MESSAGE command supports the following optional headers:
content-length—specifies the byte count for the length of the message
body. If a content-length header is included, this number of bytes should
be read, regardless of whether or not there are null characters in the body. The frame still
needs to be terminated with a null byte and if a content-length is not specified, the first
null byte encountered signals the end of the frame.
A RECEIPT frame is issued from the server whenever the client requests a
receipt for a given command. The RECEIPT frame includes a
receipt-id, containing the value of the receipt-id from
the original client request. For example, the following frame shows a typical
RECEIPT command with receipt-id header:
RECEIPT receipt-id:message-12345 ^@
The receipt body is always empty.
The server may send ERROR frames if something goes wrong. The error
frame should contain a message header with a short description of the error.
The body may contain more detailed information (or may be empty). For example, the following
frame shows an ERROR command with a non-empty body:
ERROR message: malformed packet received The message: ----- MESSAGE destined:/queue/a Hello queue a! ----- Did not contain a destination header, which is required for message propagation. ^@
The ERROR command supports the following optional headers:
content-length—specifies the byte count for the length of the message
body. If a content-length header is included, this number of bytes should
be read, regardless of whether or not there are null characters in the body. The frame still
needs to be terminated with a null byte and if a content-length is not specified, the first
null byte encountered signals the end of the frame.
Because Stomp frames consist of plain text, it is possible to improvise a Stomp client by
starting up a telnet session and entering Stomp frames directly at the
keyboard. This can be a useful diagnostic tool and is also a good way to learn about the Stomp
protocol.
While most characters in a Stomp frame are just plain text, there is one required character, null, that you might have difficulty typing at the keyboard. On some keyboards, you can type null as Ctrl-@. Other keyboards might require you to do a bit of research, however.
For example, to type a null character on the 101-key keyboard that is commonly used with a Windows PC, proceed as follows:
Enable NumLock on the numeric keypad (this is essential).
While holding down the Alt key, type zero, 0, four
times in succession on the numeric keypad.
To send and receive messages over the Stomp protocol using telnet clients, perform the following steps:
For full details of how to deploy a broker in the OSGi container, please
read Deploying a JMS Broker in Deploying into the OSGi Container. If you have not already
deployed a broker, you can create and deploy a new broker, broker1, by entering the
following console command:
karaf@root> activemq:create-broker --name broker1
Normally, the default broker is configured to initialize a Stomp connector that listens on port, 61613. Look for a line like the following in the broker’s log:
INFO TransportServerThreadSupport - Listening for connections at: stomp://localhost:61613
If the Stomp connector is not present in the broker, you will have to configure it—see Configure the broker for details.
Open a new command prompt and start a new telnet session for the
producer client, by entering the following command:
telnet
This command starts telnet in interactive mode. Now enter the following
telnet commands (the telnet prompt that begins each line
is implementation dependent):
telnet> set localecho Local echo on telnet> open localhost 61613
After entering the open command, telnet should
connect to the Stomp socket on your local ActiveMQ broker (where the Stomp port is presumed to
be 61613 here). You should now see a blank screen, where you can directly type the contents of
the Stomp frames you want to send over TCP.
Start a Stomp session for the producer by entering the following Stomp frame in the
telnet window:
CONNECT login:foo passcode:bar ^@
The login and passcode headers are currently ignored
by the ActiveMQ broker, so you can enter any values you like for these headers. Don’t
forget to insert a blank line after the headers. Finally, you must terminate the
frame by typing the null character, ^@ (for notes on how to type the null
character at your keyboard, see Typing the null character ).
If all goes well, you will see a response similar to the following:
CONNECTED session:ID:fboltond820-2290-1190810591249-3:0
Send a message to the FOO.BAR queue by entering the following
frame:
SEND destination:/queue/FOO.BAR receipt: Hello, queue FOO.BAR ^@
As soon as you have finished typing the null character, ^@, you should
receive the following RECEIPT frame from the server:
RECEIPT receipt-id:
It is a good idea to include a receipt header in the frames you send
from a telnet client. It enables you to confirm that the connection is working normally.
The status of the ActiveMQ broker can be monitored through a JMX port. To monitor the broker, start a new command prompt and enter the following command:
jconsole
The jconsole utility is a standard JMX client that is included with
Sun’s Java Development Kit (JDK). When you start the jconsole utility, a
dialog appears and prompts you to connect to a JMX process, as shown in
Figure 3.1.
Select the ActiveMQ broker process and click Connect. The main
jconsole window opens. To view the current status of the
FOO.BAR message queue, click on the MBeans tab and use
the tree on the left hand side to drill down to
org.apache.activemq/localhost/Queue/FOO.BAR. Click on the
FOO.BAR icon to view the current status, as shown in Figure 3.2.
The status shows an EnqueueCount of 1, which tells you that the
producer has successfully enqueued one message in the FOO.BAR queue.
Open a new command prompt and start a new telnet session for the
consumer client, by entering the following command:
telnet
Enter the following telnet commands to connect to the Stomp socket on
the broker:
telnet> set localecho Local echo on telnet> open localhost 61613
Start a Stomp session for the consumer by entering the following Stomp frame in the
consumer’s telnet window:
CONNECT
login:foo
passcode:bar
^@If all goes well, you will see a response similar to the following:
CONNECTED session:ID:fboltond820-2290-1190810591249-3:1
Subscribe to the FOO.BAR queue by entering the following Stomp frame in
the consumer’s telnet window:
SUBSCRIBE
destination:/queue/FOO.BAR
ack:client
^@The ack header is set to the value client, which
implies that the consumer client is expected to acknowledge each message it receives from the
broker. After typing the terminating null character, ^@, the broker
dispatches the sole message on the FOO.BAR queue by sending a
MESSAGE frame, as follows:
MESSAGE destination:/queue/FOO.BAR receipt: timestamp:1190811984837 priority:0 expires:0 message-id:ID:fboltond820-2290-1190810591249-3:0:-1:1:1 Hello, queue FOO.BAR
To see what effect this has on the queue status, go to the jconsole
window and click on the MBeans tab. The
DispatchCount attribute is now equal to 1, indicating that the broker has
dispatched the message to the consumer. The DequeueCount is equal to 0,
however; this is because the message is not considered to be dequeued until the consumer client
sends an acknowledgement.
Acknowledge the received message by entering the following Stomp frame in the consumer’s
telnet window:
ACK message-id:ID:fboltond820-2290-1190810591249-3:0:-1:1:1 ^@
Where the message ID must match the value from the message-id header in
the received MESSAGE frame. To check that the acknowledgement has been
effective, go back to the jconsole window and click
Refresh on the MBeans tab. You should now find that
the DequeueCount has increased to 1.
Unsubscribe from the FOO.BAR queue by entering the following Stomp frame
in the consumer’s telnet window:
UNSUBSCRIBE destination:/queue/FOO.BAR receipt: ^@
The demonstration code required to run these examples is available only from the standalone Apache ActiveMQ package, which you must download and install in addition to Fuse ESB.
Fuse Message Broker provides some sample code in that enables you to
experiment with the Stomp protocol in the Ruby programming language.ActiveMQInstallDir/example/ruby
You must download and install the requisite packages to support the Ruby programming language before you can run the Stomp example. Install the following packages:
Ruby programming language—download and install the Ruby programming
language from http://www.ruby-lang.org/en/downloads. Add the Ruby /bin directory to your PATH.
RubyGems package manager—RubyGems (http://www.rubygems.org) is a utility for installing and managing add-ons to the Ruby language. Download and install RubyGems as follows:
Download a RubyGems archive file (.tgz,
.zip, or .gem) from the RubyForge (http://rubyforge.org/frs/?group_id=126).
Unzip the RubyGems archive.
Initialize RubyGems by entering the following command:
ruby GemsInstallDir/setup.rbAdd to your
GemsInstallDir/binPATH.
Stomp package for Ruby—install the Stomp package for Ruby by running the following command:
gem install stomp
RubyGems downloads and installs the requisite package to support the Ruby Stomp client API.
If you have not already done so, you also need to download and install the standalone Fuse Message Broker package from fusesource.com.
To try out the Stomp protocol, perform the following steps:
For full details of how to deploy a broker in the OSGi container, please
read Deploying a JMS Broker in Deploying into the OSGi Container. If you have not already
deployed a broker, you can create and deploy a new broker, broker1, by entering the
following console command:
karaf@root> activemq:create-broker --name broker1
Check that the the Stomp connector is present in the broker configuration file (in
) as
follows:InstallDir/deploy/broker1-broker.xml
<beans>
...
<transportConnectors>
...
<transportConnector name="stomp" uri="stomp://localhost:61613"/>
</transportConnectors>
...
</beans>To connect the listener tool to the stomp://localhost:61613 endpoint
(Stomp over TCP), change directory to
ActiveMQInstallDir/example/ruby and enter the
following command:
ruby listener.rbThey Ruby listener connects to the endpoint, stomp://localhost:61613, by
default. You could change this endpoint address by editing the listener.rb
script.
To connect the publisher tool to the stomp://localhost:61613 endpoint
(Stomp over TCP), change directory to
ActiveMQInstallDir/example/ruby and enter the
following command:
ruby publisher.rb
You should see some output like the following:
Sent 1000 messages Sent 2000 messages Sent 3000 messages Sent 4000 messages Sent 5000 messages Sent 6000 messages Sent 7000 messages Sent 8000 messages Sent 9000 messages Sent 10000 messages Received report: Received 10000 in 4.567 seconds, remaining: 9
The REST protocol is a simple HTTP-based protocol that enables you to interact with the message broker using HTML forms and DHTML scripts. This chapter provides a brief introduction to the protocol, illustrating how to contact the message broker from a Web browser.
The REST protocol is a simple HTTP-based protocol that enables you to contact the message broker through a Web browser. You can contact the message broker by navigating to appropriately formatted URLs or by posting HTML forms.
The Fuse Message Broker's REST protocol is based on a subset of the HTTP protocol. Hence, HTTP is the only supported transport.
REST supports the following client types:
Web forms—use conventional HTML forms to
POST a message to a destination (queue or topic) or to
GET a message from a destination—see Example of posting a message .
Ajax clients—an Asynchronous JavaScript And Xml (Ajax) library that enables you to communicate with a REST endpoint using JavaScript in a DHTML Web page.
Representational State Transfer (REST) is a software architecture designed for distributed systems, like the World Wide Web. For details of the REST architecture and the philosophy underlying it, see the REST Wikipedia article.
One of the key concepts of a RESTful architecture is that the interaction between different network nodes should take on a very simple form. In particular, the number of operations in a RESTful protocol must be kept small: for example, the REST protocol in Fuse requires just three operations.
In general, a REST interaction consists of the following elements:
Operation—belongs to a restricted, well-known set of
operations—for example, in the HTTP protocol, the main operations are
GET, POST, PUT, and
DELETE. The advantage of this approach is that, in contrast to RPC
architectures, there is no need to define interfaces for a RESTful protocol. The
operations are all known in advance.
URI—identifies the resource that the operation acts on. For
example, a HTTP GET operation acts on the URI by fetching data from
the resource identified by the URI.
Data (if required)—needed for operations that send data to the remote resource.
HTTP is a good example of a protocol demonstrating RESTful design principles. In fact,
proponents of REST argue that it is precisely the RESTful qualities of HTTP that enabled the
rapid expansion of the World Wide Web. In keeping with REST principles, HTTP has a
restricted operation set, consisting of only eight operations: GET,
POST, PUT, DELETE,
OPTIONS, HEAD, TRACE, and
CONNECT.
For the purpose of implementing a RESTful protocol, the first four HTTP
operations—GET, POST, PUT, and
DELETE—are the most important. The semantics of these operations are
described briefly in Table 4.1 .
Table 4.1. HTTP RESTful Operations
| Operation | Description |
|---|---|
GET | Fetch the remote resource identified by the URI. |
POST | Add/append/insert data to the remote resource identified by the URI. |
PUT | Replace the remote resource identified by the URI with the data from this operation. |
DELETE | Delete the remote resource identified by the URI. |
This simple set of operations—analogous to the classic CRUD (Create, Replace, Update, and Delete) operations for a database—turns out to be remarkably powerful and flexible.
The following servlets—which are automatically deployed in the message broker Web console—implement RESTful access to the Fuse message queues:
The RESTful Web service implemented by the Fuse message servlet
enables you to enqueue and dequeue messages over HTTP. You can, therefore, use the message
servlet to implement message producers and message consumers as Web forms.
To interact with the Fuse message servlet, construct a URL of the
following form:
http://Host:Port/WebContext/message/DestinationPath?Opt1=Val1&Opt2=Val2...
Where the URL is constructed from the following parts:
Host:Port—the
host and port of the servlet engine. For example, in the default message broker
configuration, a HTTP port is opened on localhost:8161.
WebContext—in a Web application, it is usual to group
related components (servlets and so on) under a particular Web context,
WebContext. For example, for the REST demonstration
servlets, the Web context is demo by default.
message—routes this URL to the message
servlet.
DestinationPath—specifies the compound name of a queue or
topic in the message broker. For example, the FOO.BAR queue has the
destination path, FOO/BAR.
?Opt1=Val1&Opt2=Val2—you
can add some options in order to qualify how the URL is processed.
For example, the following URL can be used to fetch a message from the
FOO.BAR queue, where the Web console has the default
configuration:
http://localhost:8161/demo/message/FOO/BAR?type=queue&timeout=5000
Table 4.2 shows the URL options recognized by the
message servlet:
Table 4.2. URL Options Recognized by the Message Servlet
| URL Option | Description |
|---|---|
type | Can be either queue or topic. |
timeout | When consuming a message from a queue, specifies the length of time (in units of milliseconds) the client is prepared to wait. |
Three HTTP operations—GET, POST, and
DELETE—are recognized by the message servlet. The
semantics of these operations are described briefly in Table 4.3 .
Table 4.3. Message Servlet RESTful HTTP Operations
| Operation | Description |
|---|---|
GET | Consume a single message from the destination (queue or topic) specified by the URL. |
POST | Send a single message to the destination (queue or topic) specified by the URL. |
DELETE | Consume a single message from the destination (queue or topic) specified by the
URL. This operation has the same effect as GET. |
For details of the form properties recognized by the message servlet
(for POSTing a message), see Example of posting a message .
The RESTful Web service implemented by the queueBrowse servlet
enables you to monitor the contents and status of any queue or topic in the Web console.
Effectively, the queueBrowse servlet is a simple management tool.
To interact with the Fuse queueBrowse servlet, construct a URL of the
following form:
http://Host:Port/WebContext/queueBrowse/DestinationPath?Opt1=Val1&Opt2=Val2...
The queueBrowse URL has a similar structure to the
message URL (see message servlet ),
except that the queueBrowse URL is built from
WebContext/queueBrowse instead of
WebContext/message.
For example, the following URL can be used to browse the FOO.BAR
queue, where the Web console has the default configuration:
http://localhost:8161/demo/queueBrowse/FOO/BAR
Table 4.4 shows the URL options recognized by the
queueBrowse servlet:
Table 4.4. URL Options Recognized by the QueueBrowse Servlet
| URL Option | Description |
|---|---|
view |
Specifies the format for viewing the queue/topic. The following views are supported:
|
feedType |
In combination with the setting,
|
contentType | Override the MIME content type of the view. |
maxMessages | The maximum number of messages to render. |
Example 4.1 shows an example of the Web form used to
send a message to the FOO.BAR queue in the Web console, as demonstrated
in Send a message .
Example 4.1. Web Form for Sending a Message to a Queue or Topic
<html>
<head>
<title>Send a JMS Message</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<h1>Send a JMS Message</h1>
<form action="message/FOO/BAR" method="post">
<p>
<label for="destination">Destination name</label>
<input type="text" name="destination"/>
</p>
<p>
<label for="type">Destination Type: </label>
<select name="type">
<option selected value="queue">Queue</option>
<option type" value="topic">Topic</option>
</select>
</p>
<p>
<textarea name="body" rows="30" cols="80">
Enter some text here for the message body...
</textarea>
</p>
<p>
<input type="submit" value="Send"/>
<input type="reset"/>
</p>
</form>
</body>
</html>Table 4.5 describes the form properties that are recognized by the message servlet.
Table 4.5. Form Properties Recognized by Message Servlet
| Form Property | Description |
|---|---|
| Form action |
The |
destination | The compound name of the destination queue or topic, using a period,
., as the delimiter (for example, FOO.BAR).
If this property is specified in the form, it overrides the value of the
DestinationPath in the form action. |
type | Destination type, equals queue or
topic. |
body | Message body. |
To consume a message from a topic or queue, send a HTTP GET operation (for example, by
following a hypertext link) using the URL format described in message servlet .
For example, to consume a message from the
FOO.BAR queue, navigate to the following URL:
http://localhost:8161/demo/message/FOO/BAR?timeout=10000&type=queue
To browse a queue using the queueBrowse servlet, simply navigate to
an URL of the appropriate form, as described in queueBrowse servlet .
For example, to browse the FOO.BAR queue in XML format:
http://localhost:8161/demo/queueBrowse/FOO/BAR?view=xml
To browse the FOO.BAR queue as an Atom 1.0 feed:
http://localhost:8161/demo/queueBrowse/FOO/BAR?view=rss&feedType=atom_1.0
To browse the FOO.BAR queue as an RSS 1.0 feed:
http://localhost:8161/demo/queueBrowse/FOO/BAR?view=rss&feedType=rss_1.0
This section describes how to run the REST example, which consists of a servlet engine integral to the message broker binary, and some demonstration servlets that run as a Web application. To connect to the Web applications, you can use your favorite Web browser.
You must ensure that the message broker is configured to instantiate an embedded servlet
engine. In your broker configuration file, conf/activemq.xml, check that
there is a jetty element configured as shown in Example 4.2 .
Example 4.2. Configuration of an Embedded Servlet Engine
<!-- Embedded servlet engine for serving up the Admin console --> <jetty xmlns="http://mortbay.com/schemas/jetty/1.0"> <connectors> <nioConnector port="8161" /> </connectors> <handlers> <webAppContext contextPath="/admin" resourceBase="${activemq.base}/webapps/admin" logUrlOnStart="true" /> <webAppContext contextPath="/demo" resourceBase="${activemq.base}/webapps/demo" logUrlOnStart="true" /> </handlers> </jetty>
With the configuration shown in Example 4.2 , the servlet engine opens up a HTTP port on IP port, 8161. The following Web applications are loaded:
Demonstration application (from webapps/demo),
REST protocol servlets (from webapps/demo).
Web console servlet (from webapps/admin),
To run the REST Web example, perform the following steps:
To run the embedded servlet engine, open a new command window and enter the following command to start the default message broker:
activemq
This step assumes that your broker is configured as described in Example prerequisites.
Open your favorite Web browser (for example, Firefox or Internet Explorer) and navigate to the following URL:
http://localhost:8161/demo
Your browser should now show the welcome page for the Web examples, as shown in Figure 4.1.
To view the form for publishing messages, click the link, Send a message. The Send a JMS Message form now appears in your browser, as shown in Figure 4.2.
In the Destination name text field, enter
FOO.BAR to send a message to the FOO.BAR queue.
Leave the Destination Type as Queue. Then enter an
arbitrary text message in the large message text box. Click the Send
button at the bottom of the form to send the message.
Using the history feature of your browser, navigate back to the example welcome page
(see Figure 4.1 ). The
queueBrowse servlet supports a variety of ways to browse the contents
of a queue and these are listed at the bottom of the welcome page. The following browsing
options are listed:
If you click on Browse a queue, you should see a page like Figure 4.3 .
If you click on Browse a queue as XML, you should see a page like Figure 4.4 .
If you click on Browse a queue as Atom, you should see a page like Figure 4.5 .
If you click on Browse a queue as RSS 1.0 or Browse a queue as RSS 2.0, you should see a page like Figure 4.6 .
To receive a message from the FOO.BAR queue, open the example welcome
page in your browser, http://localhost:8161/demo, and click the link, Receive a message.
You should now see the text of the message that you sent earlier. You will probably also receive an error from your browser, if the message is not formatted as HTML or XML (which the browser expects).
The VM transport allows clients to connect to each other inside the Java Virtual Machine (JVM) without the overhead of network communication.
The VM transport enables Java clients running inside the same JVM to communicate with each other inside the JVM, without having to resort to a using a network connection. Because the clients require a broker to communicate, the VM transport can implicitly create an embedded broker the first time it is accessed. Figure 5.1 shows the basic architecture of the VM protocol.
The URI used to specify the VM transport comes in two flavors to provide maximum control over how the embedded broker is configured:
The VM transport uses a broker embedded in the same JVM as the clients to facilitate communication between the clients. The embedded broker can be created in several ways:
explicitly defining the broker in the application's configuration
explicitly creating the broker using the Java APIs
automatically when the first client attempts to connect to it using the VM transport
The VM transport uses the broker name specified in either the simple URI or in the configuration provided by the advanced URI's broker URI to determine if an embedded broker needs to be created. When a client uses the VM transport to connect to a broker, the transport checks to see if an embedded broker by that name already exists. If it does exist, the client is connected to the broker. If it does not exist, the broker is created and then the broker is connected to it.
When using explicitly created brokers there is a danger that your clients will
attempt to connect to the embedded broker before it is started. If this happens, the VM
transport will auto-create an instance of the broker for you. To avoid this conflict
you can set the waitForStart option or the create=false option
to manage how the VM transport determines when to create a new embedded broker.
The simple VM URI is used in most situations. It allows you to specify the name of the embedded broker to which the client will connect. It also allows for some basic broker configuration.
Example 5.1 shows the syntax for a simple VM URI.
BrokerName specifies the name of the embedded broker
to which the client connects.
TransportOptions specifies the configuration for the
transport. They are specified in the form of a query list. Table 5.2
lists the available options.
In addition to the transport options listed in Table 5.2, the simple VM URI can use the options described in Table 5.1 to configure the embedded broker.
Table 5.1. VM Transport Broker Configuration Options
| Option | Description |
|---|---|
broker.*
| Properties prefixed by broker. configure the embedded
broker. You can specify any of the standard broker options described in
Table 5.3. |
brokerConfig
| Specifies an external broker configuration file. For example, to pick up the
broker configuration file, activemq.xml, you would set
brokerConfig as follows:
brokerConfig=xbean:activemq.xml. |
The broker configuration options specified on the VM URI are only meaningful if the client is responsible for instantiating the embedded broker. If the embedded broker is already started, the transport will ignore the broker configuration properties.
Example 5.2 shows a basic VM URI that connects to
an embedded broker named broker1.
Example 5.3 creates and connects to an embedded broker that uses a non-persistent message store.
The advance VM URI provides you full control over how the embedded broker is configured. It uses a broker configuration URI similar to the one used by the administration tool to configure the embedded broker.
Example 5.4 shows the syntax for a simple VM URI.
BrokerConfigURI is a broker configuration URI. See
Broker URI in Administering a Message Broker for information
about broker configuration URIs.
TransportOptions specifies the configuration for the
transport. They are specified in the form of a query list. Table 5.2
lists the available options.
Example 5.5 creates and connects to an embedded broker configured using a broker configuration URI.
Table 5.2 shows options for configuring the VM transport.
Table 5.2. VM Transport Options
Table 5.3 shows the options used to configure the broker using the simple VM URI.
Table 5.3. Broker Options
The failover protocol provides a simple mechanism for clients to failover to a secondary broker endpoint if the primary connection fails. The failover protocol does not require that the brokers be configured as a network of brokers. However, when paired with a network of brokers it can be configured to use dynamic failover locations.
The failover protocol facilitates quick recovery from network failures. When a recoverable network error occurs the protocol catches the error and automatically attempts to reestablish the JMS connection to an alternate broker endpoint without the need to recreate all of the JMS objects associated with the JMS connection. The failover URI is composed of one or more URIs that represent different broker endpoints. By default, the protocol randomly chooses a URI from the list and attempts to establish a network connection to it. If it does not succeed, or if it subsequently fails, a new network connection is established to one of the other URIs in the list.
For true high-availability and failover capabilities, you will need to set up your brokers in a network of brokers or a master/slave cluster. See Clustering Guide.
The failover transport allows you to set up failover in one of two ways:
In static failover a client is configured to use a failover IRU that lists the URIs of the broker connections the client can use. When establishing a connection, the client randomly chooses a URI from the list and attempts to establish a connection to it. If the connection does not succeed, the client chooses a new URI from the list and tries again. The client will continue cycling through the list until a connection attempt succeeds.
If a client's connection to a broker fails after it has been established, the client will attempt to reconnect to a different broker in the list. Once a connection to a new broker is established, the client will continue to use the new broker until the connection to the new broker is severed.
A failover URI is a composite URI that uses one of the following syntaxes:
failover://uri1,...,uriN
failover://(uri1,...,uriN)?TransportOptions
The URI list()
is a comma-separated list containing the list of broker endpoint URIs to which the client can
connect. The transport options(uri1,...,uriN?)
specified in the form of a query list, allow you to configure some of the failoiver
behaviors.TransportOptions
The failover protocol supports the transport options described in Table 6.1.
Table 6.1. Failover Transport Options
| Option | Default | Description |
|---|---|---|
initialReconnectDelay
| 10 | Specifies the number of milliseconds to wait before the first reconnect attempt. |
maxReconnectDelay
| 30000 | Specifies the maximum amount of time, in milliseconds, to wait between reconnect attempts. |
useExponentialBackOff
| true | Specifies whether to use an exponential back-off between reconnect attempts. |
backOffMultiplier
| 2 | Specifies the exponent used in the exponential back-off algorithm. |
maxReconnectAttempts
| -1 | Specifies the maximum number of reconnect attempts before an error is returned to the client. -1 specifies unlimited attempts. 0 specifies that an initial connection attempt is made at start-up, but no attempts to failover over to a secondary broker will be made. |
startupMaxReconnectAttempts
| 0 | Specifies the maximum number of reconnect attempts before an error is returned to the client on the first attempt by the client to start a connection. 0 specifies unlimited attempts. |
randomize
| true | Specifies if a URI is chosen at random from the list. Otherwise, the list is traversed from left to right. |
backup
| false | Specifies if the protocol initializes and holds a second transport connection to enable fast failover. |
timeout
| -1 | Specifies the amount of time, in milliseconds, to wait before sending an error if a new connection is not established. -1 specifies an infinite timeout value. |
trackMessages
| false | Specifies if the protocol keeps a cache of in-flight messages that are flushed to a broker on reconnect. |
maxCacheSize
| 131072 | Specifies the size, in bytes, used for the cache used to track messages. |
updateURIsSupported
| true | Specifies whether the client accepts updates to its list of known URIs from the connected broker. Setting this to false inhibits the client's ability to use dynamic failover. See Dynamic Failover. |
Example 6.1 shows a failover URI that can connect to one of two message brokers.
Example 6.1. Simple Failover URI
failover://(tcp://localhost:61616,tcp://remotehost:61616)?initialReconnectDelay=100
Dynamic failover combines the failover protocol and a network of brokers to allow a broker to supply its clients with a list of broker connections to which the clients can failover. Clients use a failover URI to connect to a broker and the broker dynamically updates the clients' list of available URIs. The broker updates its clients' failover lists with the URIs of the other brokers in its network of brokers that are currently running. As new brokers join, or exit, the cluster, the broker will adjust its clients' failover lists.
From a connectivity point of view, dynamic failover works the same as static failover. A client randomly chooses a URI from the list provided in its failover URI. Once that connection is established, the list of available brokers is updated. If the original connection fails, the client will randomly select a new URI from its dynamically generated list of brokers. If the new broker is configured for dynamic failover, the new broker will update the client's list.
To use dynamic failover you must configure both the clients and brokers used by your application. The following must be configured:
The client's must be configured to use the failover protocol when connecting with its broker.
The brokers must be configured to form a network of brokers.
See Broker Networks in Clustering Guide.
The broker's transport connector must set the failover properties needed to update its consumers.
The client-side configuration for using dynamic failover is identical to the client-side configuration for using static failover. The client uses a failover URI to connect to a broker.
When using dynamic failover, the failover URI can include a single broker URI. As long as the broker is available when the client attempts to make its initial connection, the client's list of failover brokers will get populated.
It is also important that the updateURIsSupported option not be set to
false. If it is, the client will not be able to receive updates about what
brokers are available for failover.
See Failover URI and Transport options for more information about using failover URIs.
Configuring a broker to participate in dynamic failover requires two things:
The broker must be configured to participate in a network of brokers that can be available for failovers.
See Broker Networks in Clustering Guide for information about setting up a network of brokers.
The broker's transport connector must set the failover properties needed to update its consumers.
Table 6.2 describes the broker-side properties
that can be used to configure a failover cluster. These properties are attributes on the
broker's transportConnector element.
Table 6.2. Broker-side Failover Properties
Example 6.2 shows the configuration for a broker that participates in dynamic failover.
Example 6.2. Broker for Dynamic Failover
<beans ... > <broker> ... <networkConnectors><networkConnector uri="multicast://default" /> </networkConnectors> ... <transportConnectors> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616"
discoveryUri="multicast://default"
updateClusterClients="true"
updateClusterFilter="*A*,*B*" /> </transportConnectors> ... </broker> </beans>
The configuration in Example 6.2 does the following:
Creates a network connector that connects to any discoverable broker that uses the multicast transport. | |
Makes the broker discoverable by other brokers over the multicast protocol. | |
Makes the broker update the list of available brokers for clients that connect using the failover protocol. NoteClients will only be updated when new brokers join the cluster, not when a broker leaves the cluster. | |
Creates a filter so that only those brokers whose names start with the letter
|
Example 6.3 shows the URI for a client that uses the failover protocol to connect to the broker and its cluster.
Example 6.3. Failover URI for Connecting to a Failover Cluster
failover://(tcp://0.0.0.0:61616)?initialReconnectDelay=100
This chapter introduces the simplest kind of broker cluster: a collection of isolated broker instances (no network connectors). When used in combination with the discovery protocols, such a cluster can be used as a simple load balancing system.
The dynamic discovery protocol combines reconnect logic with the capability to auto-discover broker endpoints in the local network. The discovery protocol invokes a discovery agent in order to build up a list of broker URIs. The protocol then randomly chooses a URI from the list and attempts to establish a connection to it. If it does not succeed, or if it subsequently fails, a new connection is established to one of the other URIs in the list.
A discovery agent is a bootstrap mechanism that enables a message broker, consumer, or producer to obtain a list of broker URIs, where the URIs represent connector endpoints. The broker, consumer, or producer can subsequently connect to one of the URIs in the list.
The following kinds of discovery agent are currently supported in Fuse Message Broker:
Simple (static) discovery agent.
Multicast discovery agent.
Zeroconf discovery agent.
For more details, see Discovery Agents.
Before you can use the discovery protocol, you must make your broker’s endpoints
discoverable by adding a discovery agent to each transport connector. For example,
to make a TCP transport connector discoverable, set the
discoveryUri attribute on the
transportConnector element as follows:
<transportConnectors> <transportConnector name="openwire" uri="tcp://localhost:61716" discoveryUri="multicast://default"/> </transportConnectors>
Where the TCP transport connector is configured to use the multicast discovery
agent, multicast://default.
A discovery URI must conform to the following syntax:
discovery://(DiscoveryAgentUri)?TransportOptions
Where the discovery agent URI, DiscoveryAgentUri,
identifies a discovery agent, as described in Discovery agents above. The transport options,
?TransportOptions, are specified
in the form of a query list (where the supported options are described in Table 7.1 ). If no transport options are
required, you can use the following alternative syntax:
discovery://DiscoveryAgentUriThe discovery protocol supports the transport options described in Table 7.1
Table 7.1. Discovery Transport Options
| Option Name | Default | Description |
|---|---|---|
initialReconnectDelay | 10 | How long to wait before the first reconnect attempt (in ms). |
maxReconnectDelay | 30000 | The maximum amount of time to wait between reconnect attempts (in ms). |
useExponentialBackOff | true | If true, use an exponential back-off between
reconnect attempts. |
backOffMultiplier | 2 | The exponent used in the exponential back-off algorithm. |
maxReconnectAttempts | 0 | If not 0, this is the maximum number of
reconnect attempts before an error is sent back to the
client. |
The following is an example of a discovery URI that uses a multicast discovery agent:
discovery://(multicast://default)?initialReconnectDelay=100
The list of transport options, TransportOptions, in the
discovery URI can also be used to set options on the discovered
transports. If you set an option not listed in Table 7.1, the URI parser attempts to inject the option setting into
every one of the discovered endpoints.
For example, if you set the TCP connectionTimeout option to 10
seconds, as follows:
discovery://(multicast://default)?connectionTimeout=10000
The 10 second timeout setting is injected into every discovered TCP endpoint.
A discovery agent is a bootstrap mechanism that enables a client or message broker to discover other broker instances on a network. A discover agent URI is used on the client side and on the broker side, as follows:
Client side—the discovery agent URI resolves to
a list of broker URIs. To use a discovery agent URI on the client side, you
must insert it into a dynamic discovery URI,
discovery://(...), which then opens a connection to
one of the URIs in the list.
Broker side—in order to make a broker
discoverable, it is usually necessary to configure a discovery agent in the
broker as well (an exception to this requirement is the
simple discovery agent).
A discover agent URI resolves to a list of transport URIs, but the discovery agent URI is not itself a transport URI and cannot be used in place of a transport URI.
Since a discovery agent is not a transport protocol, you cannot use a discovery
agent URI directly on the client side. To use a discovery agent on the client side,
embed the agent URI,DiscoveryAgentUri, inside a discovery
URL, as follows:
discovery://(DiscoveryAgentUri)?TransportOptions
The client recognizes the discovery URL as a transport. It first obtains a list of available endpoint URLs using the specified discovery agent and then connects to one of the discovered URLs. For more details about the discovery protocol, see Dynamic Discovery Protocol .
For certain kinds of discovery agent (for example, multicast or zeroconf), it is
necessary to enable the discovery agent in the message broker configuration. For
example, to enable the multicast discovery agent on an Openwire endpoint, edit the
relevant transportConnector element as follows:
<transportConnectors> <transportConnector name="openwire" uri="tcp://localhost:61716" discoveryUri="multicast://default"/> </transportConnectors>
Where the discoveryUri attribute on the
transportConnector element is initialized to
multicast://default. You can associate multiple endpoints
with the same discovery agent. For example, to configure both an Openwire endpoint
and a Stomp endpoint to use the multicast://default discovery
agent:
<transportConnectors> <transportConnector name="openwire" uri="tcp://localhost:61716" discoveryUri="multicast://default"/> <transportConnector name="stomp" uri="stomp://localhost:61613" discoveryUri="multicast://default"/> </transportConnectors>
Fuse Message Broker currently supports the following discovery agents:
The simple (static) discovery agent provides an explicit list of broker URLs for a client to connect to. For example:
simple://(tcp://localhost:61716,tcp://localhost:61816)
In general, the URI for a simple discovery agent must conform to the following syntax:
simple://(URI1,URI2,URI3,...)
Or equivalently:
static://(URI1,URI2,URI3,...)
The two prefixes, simple: and static:, are
exactly equivalent. In order to use the agent URI, it must be
embedded inside a discovery URL—for example:
discovery://(static://(tcp://localhost:61716,tcp://localhost:61816))
This discovery agent is only used on the client side. No extra configuration is required in the broker.
The multicast discovery agent uses the IP multicast
protocol to find any message brokers currently active on the local network. In order
for the protocol to work, a multicast discovery agent must be enabled on
each broker you want to advertise and messaging clients
must be configured to use a discovery URI.
The URI for a multicast discovery agent must conform to the following syntax:
multicast://GroupIDWhere the GroupID is an alphanumeric identifier. All
participants in the same discovery network must use the same
GroupID. For example, the Fuse Message Broker is
usually configured to use the URI, multicast://default.
Your local network (LAN) must be configured appropriately for the IP/multicast
protocol to work. If your clients fail to discover a broker using the
multicast protocol, this could be because IP/multicast is not
set up on your network.
The zeroconf discovery agent is derived from Apple’s
Bonjour
Networking technology, which defines the zeroconf protocol as a
mechanism for discovering services on a network. Fuse Message Broker bases its implementation
of the zeroconf discovery agent on JmDSN, which is a
service discovery protocol that is layered over IP/multicast and is compatible with
Apple Bonjour. To enable the protocol, a multicast discovery agent must be
configured on each broker you want to advertise and messaging
clients must be configured to use a discovery URI.
The URI for a zeroconf discovery agent must conform to the following syntax:
zeroconf://GroupIDWhere the GroupID is an alphanumeric identifier. All
participants in the same discovery network must use the same
GroupID.
For example, to use a zeroconf discovery agent on the client side, where the
client needs to connect to the groupA group, you would construct
a discovery URL like the following:
discovery://(zeroconf://groupA)
Your local network (LAN) must be configured appropriately for the IP/multicast
protocol to work. If your clients fail to discover a broker using the
zeroconf protocol, this could be because IP/multicast is not
set up on your network.
The TCP transport is used for creating OpenWire/TCP endpoints. The NIO transport is similar to the TCP transport, except that it uses the Java New I/O (NIO) socket library, which can provide better scalability when used on the server side. TCP and NIO have the same transport options.
A TCP URI has the following syntax:
tcp://Host[:Port]?transportOptions
An NIO URI has the following syntax:
nio://Host[:Port]?transportOptions
Where the transport options, transportOptions, are specified
as follows:
?option=value&option=value&...
In XML configuration, you must escape the & symbol, replacing it with
&. For example:
?option=value&option=value&...
When setting a client-side option, the name of the options is exactly as given in Table A.1. For example, to enable tracing on a client TCP
endpoint, set the trace option as follows:
tcp://fusesource.com:61616?trace=trueWhen setting a server-side option, there are two alternative option syntaxes as follows:
To configure options on the TCP listener socket, add the transport.
prefix to the option names shown in Table A.1. For
example, to enable tracing on a TCP listener socket, set the trace option
as follows:
tcp://fusesource.com:61616?transport.trace=trueTo configure options on a TCP connection socket (which is spawned from the
listener socket whenever the server accepts a new TCP connection), use the option name
exactly as given in Table A.1. For example, to enable
tracing on a TCP connection socket, set the trace option as
follows:
tcp://fusesource.com:61616?trace=trueTable A.1 shows the options supported by the TCP and the NIO URIs.
Table A.1. TCP and NIO Transport Options
| Option | Default | Description |
|---|---|---|
minmumWireFormatVersion | 0 | The minimum wire format version that is allowed. |
trace | false | Causes all commands sent over the transport to be logged. |
daemon | false | Specifies whether the transport thread runs as a daemon or not. Useful to enable when embedding in a Spring container or in a web container, to allow the container to shut down properly. |
useLocalHost | true | When true, causes the local machine's name to resolve to
localhost. |
socketBufferSize | 64*1024 | Sets the socket buffer size in bytes. |
keepAlive | false | When true, enables TCP
KeepAlive on the broker connection. Useful to ensure that inactive
consumers do not time out. |
soTimeout | 0 | Sets the socket timeout in milliseconds |
connectionTimeout | 30000 | A non-zero value specifies the connection timeout in milliseconds. A zero value means wait forever for the connection to be established. Negative values are ignored. |
closeAsync | true | The false value causes all sockets to be closed
synchronously. |
soLinger | MIN_INTEGER | When > -1, enables the SoLinger socket option with this value.
When equal to -1, disables SoLinger. (from 5.6.0). |
maximumConnections | MAX_VALUE | The maximum number of sockets the broker is allowed to create. |
diffServ | 0 | (Client only) The preferred Differentiated Services
traffic class to be set on outgoing packets, as described in RFC 2475. Valid integer
values are [0,64). Valid string values are EF,
AF[1-3][1-4] or CS[0-7]. With JDK 6, only works when the
Java Runtime uses the IPv4 stack, which can be done by setting the
java.net.preferIPv4Stack system property to true. Cannot
be used at the same time as the typeOfService option. |
typeOfService | 0 | (Client only) The preferred type of
service value to be set on outgoing packets. Valid integer values are
[0,256). With JDK 6, only works when the Java Runtime uses the IPv4
stack, which can be done by setting the java.net.preferIPv4Stack system
property to true. Cannot be used at the same time as the
diffServ option. |
wireFormat | The name of the wire format to use. | |
wireFormat.* | All the properties with this prefix are used to configure the wireFormat. See Table A.4 for more information. |
The SSL transport is used for creating OpenWire/TCP endpoints with SSL/TLS enabled.
The URI transport options described here are not sufficient to configure an SSL endpoint completely. You must also associate X.509 certificates with the endpoint. For more details, see SSL/TLS Security in ActiveMQ Security Guide.
An SSL URI has the following syntax:
ssl://Host[:Port]?transportOptions
Where the transport options, transportOptions, are specified
as follows:
?option=value&option=value&...
In XML configuration, you must escape the & symbol, replacing it with
&. For example:
?option=value&option=value&...
The SSL transport inherits all of the options supported by the TCP transport URI. See Table A.1.
Table A.2 shows the options supported by the SSL URI.
Table A.2. SSL Transport Options
| Option | Default | Description |
|---|---|---|
transport.enabledCipherSuites | Specifies the cipher suites accepted by this endpoint, in the form of a comma-separated list. | |
transport.enabledProtocols | Specifies the secure socket protocols accepted by this endpoint, in the form of
a comma-separated list. If using Sun's JSSE provider, possible values are:
SSL, SSLv2, SSLv3, TLS, or
TLSv1. | |
transport.wantClientAuth | (Server only) If true, the server requests
(but does not require) the client to send a certificate. | |
transport.needClientAuth | false | (Server only) If true, the server
requires the client to send its certificate. If the client
fails to send a certificate, the server will throw an error and close the
session. |
transport.enableSessionCreation | true | (Server only) If true, the server socket
creates a new SSL session every time it accepts a connection and spawns a new
socket. If false, an existing SSL session must be resumed when the
server socket accepts a connection. |
The UDP transport enables you to send datagrams using the unreliable UDP/IP protocol.
Because UDP does not keep track of IP packets, you can lose messages sent over a raw UDP connection. It is up to you to provide a reliability layer to avoid message loss over UDP.
A UDP URI has the following syntax:
udp://Host[:Port]?transportOptions
Where the transport options, transportOptions, are specified
as follows:
?option=value&option=value&...
In XML configuration, you must escape the & symbol, replacing it with
&. For example:
?option=value&option=value&...
Table A.3 shows the options supported by the UDP URI.
Table A.3. SSL Transport Options
| Option | Default | Description |
|---|---|---|
minmumWireFormatVersion | 0 | The minimum version wire format that is allowed. |
trace | false | Causes all commands sent over the transport to be logged. |
useLocalHost | true | When true, causes the local machine's name to resolve to
localhost. |
datagramSize | 4*1024 | Specifies the size of a datagram. |
wireFormat | The name of the wire format to use. | |
wireFormat.* | All options with this prefix are used to configure the wire format. See Table A.4 for more information. |
The wire format options configure the OpenWire message layer and can be specified as transport options with any of the preceding transports.
Table A.4 shows the wire format options supported by the OpenWire protocol.
Table A.4. Transport Options Supported by OpenWire Protocol
| Option | Default | Description | Negotiation policy |
|---|---|---|---|
wireformat
.stackTraceEnabled | true |
Should the stack trace of an exception occuring on the broker be sent to the client? |
Set to |
wireformat
.tcpNoDelayEnabled | false |
Provides a hint to the peer that TCP |
Set to |
wireformat
.cacheEnabled | true |
Should commonly repeated values be cached so that less marshalling occurs? |
Set to |
wireformat
.cacheSize | 1024 |
If |
Use the smaller of the two values. |
wireformat
.tightEncodingEnabled | true |
Should wire size be optimized over CPU usage? |
Set to |
wireformat
.prefixPacketSize | true |
Should the size of the packet be prefixed before each packet is marshalled? |
Set to |
wireformat
.maxInactivityDuration | 30000 |
The maximum inactivity duration (before which the socket is considered dead)
in milliseconds. On some platforms it can take a long time for a socket to appear
to die, so we allow the broker to kill connections if they are inactive for a
period of time. Set to a value |
Use the smaller of the two values. |
wireformat
.maxInactivityDurationInitalDelay | 10000 | The initial delay in starting the maximum inactivity checks. Note: The mis-spelling, Inital, is a
typographic error in the source code. |