1119 lines
68 KiB
XML
1119 lines
68 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!-- ============================================================================= -->
|
||
<!-- Copyright © 2009 Red Hat, Inc. and others. -->
|
||
<!-- -->
|
||
<!-- The text of and illustrations in this document are licensed by Red Hat under -->
|
||
<!-- a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). -->
|
||
<!-- -->
|
||
<!-- An explanation of CC-BY-SA is available at -->
|
||
<!-- -->
|
||
<!-- http://creativecommons.org/licenses/by-sa/3.0/. -->
|
||
<!-- -->
|
||
<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation -->
|
||
<!-- of it, you must provide the URL for the original version. -->
|
||
<!-- -->
|
||
<!-- Red Hat, as the licensor of this document, waives the right to enforce, -->
|
||
<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent -->
|
||
<!-- permitted by applicable law. -->
|
||
<!-- ============================================================================= -->
|
||
|
||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||
<!ENTITY % BOOK_ENTITIES SYSTEM "HornetQ_User_Manual.ent">
|
||
%BOOK_ENTITIES;
|
||
]>
|
||
<chapter id="management">
|
||
<title>Management</title>
|
||
<para>HornetQ has an extensive management API that allows a user to modify a server
|
||
configuration, create new resources (e.g. JMS queues and topics), inspect these resources
|
||
(e.g. how many messages are currently held in a queue) and interact with it (e.g. to remove
|
||
messages from a queue). All the operations allows a client to <emphasis>manage</emphasis>
|
||
HornetQ. It also allows clients to subscribe to management notifications.</para>
|
||
<para>There are 3 ways to manage HornetQ:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Using JMX -- JMX is the standard way to manage Java applications</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Using the core API -- management operations are sent to HornetQ server using
|
||
<emphasis>core messages</emphasis></para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Using the JMS API -- management operations are sent to HornetQ server using
|
||
<emphasis>JMS messages</emphasis></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>Although there are 3 different ways to manage HornetQ each API supports the same
|
||
functionality. If it is possible to manage a resource using JMX it is also possible to achieve
|
||
the same result using Core messages or JMS messages.</para>
|
||
<para>This choice depends on your requirements, your application settings and your environment to
|
||
decide which way suits you best.</para>
|
||
<section>
|
||
<title>The Management API</title>
|
||
<para>Regardless of the way you <emphasis>invoke</emphasis> management operations, the
|
||
management API is the same.</para>
|
||
<para>For each <emphasis>managed resource</emphasis>, there exists a Java interface describing
|
||
what can be invoked for this type of resource.</para>
|
||
<para>HornetQ exposes its managed resources in 2 packages:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><emphasis>Core</emphasis> resources are located in the <literal
|
||
>org.apache.activemq6.api.core.management</literal> package</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><emphasis>JMS</emphasis> resources are located in the <literal
|
||
>org.apache.activemq6.api.jms.management</literal> package</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>The way to invoke a <emphasis>management operations</emphasis> depends whether JMX, core
|
||
messages, or JMS messages are used.</para>
|
||
<note>
|
||
<para>A few management operations requires a <literal>filter</literal> parameter to chose
|
||
which messages are involved by the operation. Passing <literal>null</literal> or an
|
||
empty string means that the management operation will be performed on <emphasis>all
|
||
messages</emphasis>.</para>
|
||
</note>
|
||
<section>
|
||
<title>Core Management API</title>
|
||
<para>HornetQ defines a core management API to manage core resources. For full details of
|
||
the API please consult the javadoc. In summary:</para>
|
||
<section id="management.core.server">
|
||
<title>Core Server Management</title>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Listing, creating, deploying and destroying queues</para>
|
||
<para>A list of deployed core queues can be retrieved using the <literal
|
||
>getQueueNames()</literal> method.</para>
|
||
<para>Core queues can be created or destroyed using the management operations
|
||
<literal>createQueue()</literal> or <literal>deployQueue()</literal> or
|
||
<literal>destroyQueue()</literal>)on the <literal
|
||
>HornetQServerControl</literal> (with the ObjectName <literal
|
||
>org.apache.activemq6:module=Core,type=Server</literal> or the resource name <literal
|
||
>core.server</literal>)</para>
|
||
<para><literal>createQueue</literal> will fail if the queue already exists while
|
||
<literal>deployQueue</literal> will do nothing.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Pausing and resuming Queues</para>
|
||
<para>The <literal>QueueControl</literal> can pause and resume the underlying
|
||
queue. When a queue is paused, it will receive messages but will not deliver
|
||
them. When it's resumed, it'll begin delivering the queued messages, if any.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Listing and closing remote connections</para>
|
||
<para>Client's remote addresses can be retrieved using <literal
|
||
>listRemoteAddresses()</literal>. It is also possible to close the
|
||
connections associated with a remote address using the <literal
|
||
>closeConnectionsForAddress()</literal> method.</para>
|
||
<para>Alternatively, connection IDs can be listed using <literal
|
||
>listConnectionIDs()</literal> and all the sessions for a given connection
|
||
ID can be listed using <literal>listSessions()</literal>.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Transaction heuristic operations</para>
|
||
<para>In case of a server crash, when the server restarts, it it possible that
|
||
some transaction requires manual intervention. The <literal
|
||
>listPreparedTransactions()</literal> method lists the transactions which
|
||
are in the prepared states (the transactions are represented as opaque Base64
|
||
Strings.) To commit or rollback a given prepared transaction, the <literal
|
||
>commitPreparedTransaction()</literal> or <literal
|
||
>rollbackPreparedTransaction()</literal> method can be used to resolve
|
||
heuristic transactions. Heuristically completed transactions can be listed
|
||
using the <literal>listHeuristicCommittedTransactions()</literal> and <literal
|
||
>listHeuristicRolledBackTransactions</literal> methods.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Enabling and resetting Message counters</para>
|
||
<para>Message counters can be enabled or disabled using the <literal
|
||
>enableMessageCounters()</literal> or <literal
|
||
>disableMessageCounters()</literal> method. To reset message counters, it is
|
||
possible to invoke <literal>resetAllMessageCounters()</literal> and <literal
|
||
>resetAllMessageCounterHistories()</literal> methods.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Retrieving the server configuration and attributes</para>
|
||
<para>The <literal>HornetQServerControl</literal> exposes HornetQ server
|
||
configuration through all its attributes (e.g. <literal>getVersion()</literal>
|
||
method to retrieve the server's version, etc.)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Listing, creating and destroying Core bridges and diverts</para>
|
||
<para>A list of deployed core bridges (resp. diverts) can be retrieved using the <literal
|
||
>getBridgeNames()</literal> (resp. <literal>getDivertNames()</literal>) method.</para>
|
||
<para>Core bridges (resp. diverts) can be created or destroyed using the management operations
|
||
<literal>createBridge()</literal> and <literal>destroyBridge()</literal>
|
||
(resp. <literal>createDivert()</literal> and <literal>destroyDivert()</literal>) on the <literal
|
||
>HornetQServerControl</literal> (with the ObjectName <literal
|
||
>org.apache.activemq6:module=Core,type=Server</literal> or the resource name <literal
|
||
>core.server</literal>).</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>It is possible to stop the server and force failover to occur with any currently attached clients.</para>
|
||
<para>to do this use the <literal>forceFailover()</literal> on the <literal
|
||
>HornetQServerControl</literal> (with the ObjectName <literal
|
||
>org.apache.activemq6:module=Core,type=Server</literal> or the resource name <literal
|
||
>core.server</literal>) </para>
|
||
<note>
|
||
<para>Since this method actually stops the server you will probably receive some sort of error
|
||
depending on which management service you use to call it.
|
||
</para>
|
||
</note>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>Core Address Management</title>
|
||
<para>Core addresses can be managed using the <literal>AddressControl</literal> class
|
||
(with the ObjectName <literal>org.apache.activemq6:module=Core,type=Address,name="<the
|
||
address name>"</literal> or the resource name <literal>core.address.<the
|
||
address name></literal>). </para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Modifying roles and permissions for an address</para>
|
||
<para>You can add or remove roles associated to a queue using the <literal
|
||
>addRole()</literal> or <literal>removeRole()</literal> methods. You can
|
||
list all the roles associated to the queue with the <literal
|
||
>getRoles()</literal> method</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>Core Queue Management</title>
|
||
<para>The bulk of the core management API deals with core queues. The <literal
|
||
>QueueControl</literal> class defines the Core queue management operations (with
|
||
the ObjectName <literal>org.apache.activemq6:module=Core,type=Queue,address="<the bound
|
||
address>",name="<the queue name>"</literal> or the resource name <literal
|
||
>core.queue.<the queue name></literal>).</para>
|
||
<para>Most of the management operations on queues take either a single message ID (e.g.
|
||
to remove a single message) or a filter (e.g. to expire all messages with a given
|
||
property.)</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Expiring, sending to a dead letter address and moving messages</para>
|
||
<para>Messages can be expired from a queue by using the <literal
|
||
>expireMessages()</literal> method. If an expiry address is defined,
|
||
messages will be sent to it, otherwise they are discarded. The queue's
|
||
expiry address can be set with the <literal>setExpiryAddress()</literal>
|
||
method.</para>
|
||
<para>Messages can also be sent to a dead letter address with the <literal
|
||
>sendMessagesToDeadLetterAddress()</literal> method. It returns the number
|
||
of messages which are sent to the dead letter address. If a dead letter address
|
||
is not defined, message are removed from the queue and discarded. The queue's
|
||
dead letter address can be set with the <literal
|
||
>setDeadLetterAddress()</literal> method.</para>
|
||
<para>Messages can also be moved from a queue to another queue by using the
|
||
<literal>moveMessages()</literal> method.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Listing and removing messages</para>
|
||
<para>Messages can be listed from a queue by using the <literal
|
||
>listMessages()</literal> method which returns an array of <literal
|
||
>Map</literal>, one <literal>Map</literal> for each message.</para>
|
||
<para>Messages can also be removed from the queue by using the <literal
|
||
>removeMessages()</literal> method which returns a <literal
|
||
>boolean</literal> for the single message ID variant or the number of
|
||
removed messages for the filter variant. The <literal
|
||
>removeMessages()</literal> method takes a <literal>filter</literal>
|
||
argument to remove only filtered messages. Setting the filter to an empty
|
||
string will in effect remove all messages.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Counting messages</para>
|
||
<para>The number of messages in a queue is returned by the <literal
|
||
>getMessageCount()</literal> method. Alternatively, the <literal
|
||
>countMessages()</literal> will return the number of messages in the queue
|
||
which <emphasis>match a given filter</emphasis></para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Changing message priority</para>
|
||
<para>The message priority can be changed by using the <literal
|
||
>changeMessagesPriority()</literal> method which returns a <literal
|
||
>boolean</literal> for the single message ID variant or the number of
|
||
updated messages for the filter variant.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Message counters</para>
|
||
<para>Message counters can be listed for a queue with the <literal
|
||
>listMessageCounter()</literal> and <literal
|
||
>listMessageCounterHistory()</literal> methods (see <xref
|
||
linkend="management.message-counters"/>). The message counters can also be
|
||
reset for a single queue using the <literal>resetMessageCounter()</literal>
|
||
method.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Retrieving the queue attributes</para>
|
||
<para>The <literal>QueueControl</literal> exposes Core queue settings through its
|
||
attributes (e.g. <literal>getFilter()</literal> to retrieve the queue's filter
|
||
if it was created with one, <literal>isDurable()</literal> to know whether the
|
||
queue is durable or not, etc.)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Pausing and resuming Queues</para>
|
||
<para>The <literal>QueueControl</literal> can pause and resume the underlying
|
||
queue. When a queue is paused, it will receive messages but will not deliver
|
||
them. When it's resume, it'll begin delivering the queued messages, if any.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>Other Core Resources Management</title>
|
||
<para>HornetQ allows to start and stop its remote resources (acceptors, diverts,
|
||
bridges, etc.) so that a server can be taken off line for a given period of time
|
||
without stopping it completely (e.g. if other management operations must be performed
|
||
such as resolving heuristic transactions). These resources are:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Acceptors</para>
|
||
<para>They can be started or stopped using the <literal>start()</literal> or.
|
||
<literal>stop()</literal> method on the <literal>AcceptorControl</literal>
|
||
class (with the ObjectName <literal
|
||
>org.apache.activemq6:module=Core,type=Acceptor,name="<the acceptor
|
||
name>"</literal> or the resource name <literal>core.acceptor.<the
|
||
address name></literal>). The acceptors parameters can be retrieved using
|
||
the <literal>AcceptorControl</literal> attributes (see <xref
|
||
linkend="configuring-transports.acceptors"/>)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Diverts</para>
|
||
<para>They can be started or stopped using the <literal>start()</literal> or
|
||
<literal>stop()</literal> method on the <literal>DivertControl</literal>
|
||
class (with the ObjectName <literal
|
||
>org.apache.activemq6:module=Core,type=Divert,name=<the divert name></literal>
|
||
or the resource name <literal>core.divert.<the divert name></literal>).
|
||
Diverts parameters can be retrieved using the <literal>DivertControl</literal>
|
||
attributes (see <xref linkend="diverts"/>)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Bridges</para>
|
||
<para>They can be started or stopped using the <literal>start()</literal> (resp.
|
||
<literal>stop()</literal>) method on the <literal>BridgeControl</literal>
|
||
class (with the ObjectName <literal
|
||
>org.apache.activemq6:module=Core,type=Bridge,name="<the bridge
|
||
name>"</literal> or the resource name <literal>core.bridge.<the bridge
|
||
name></literal>). Bridges parameters can be retrieved using the <literal
|
||
>BridgeControl</literal> attributes (see <xref linkend="core-bridges"
|
||
/>)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Broadcast groups</para>
|
||
<para>They can be started or stopped using the <literal>start()</literal> or
|
||
<literal>stop()</literal> method on the <literal
|
||
>BroadcastGroupControl</literal> class (with the ObjectName <literal
|
||
>org.apache.activemq6:module=Core,type=BroadcastGroup,name="<the broadcast group
|
||
name>"</literal> or the resource name <literal
|
||
>core.broadcastgroup.<the broadcast group name></literal>). Broadcast
|
||
groups parameters can be retrieved using the <literal
|
||
>BroadcastGroupControl</literal> attributes (see <xref
|
||
linkend="clusters"/>)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Discovery groups</para>
|
||
<para>They can be started or stopped using the <literal>start()</literal> or
|
||
<literal>stop()</literal> method on the <literal
|
||
>DiscoveryGroupControl</literal> class (with the ObjectName <literal
|
||
>org.apache.activemq6:module=Core,type=DiscoveryGroup,name="<the discovery group
|
||
name>"</literal> or the resource name <literal>core.discovery.<the
|
||
discovery group name></literal>). Discovery groups parameters can be
|
||
retrieved using the <literal>DiscoveryGroupControl</literal> attributes (see
|
||
<xref linkend="clusters"/>)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Cluster connections</para>
|
||
<para>They can be started or stopped using the <literal>start()</literal> or
|
||
<literal>stop()</literal> method on the <literal
|
||
>ClusterConnectionControl</literal> class (with the ObjectName <literal
|
||
>org.apache.activemq6:module=Core,type=ClusterConnection,name="<the cluster
|
||
connection name>"</literal> or the resource name <literal
|
||
>core.clusterconnection.<the cluster connection name></literal>).
|
||
Cluster connections parameters can be retrieved using the <literal
|
||
>ClusterConnectionControl</literal> attributes (see <xref
|
||
linkend="clusters"/>)</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>JMS Management API</title>
|
||
<para>HornetQ defines a JMS Management API to manage JMS <emphasis>administrated
|
||
objects</emphasis> (i.e. JMS queues, topics and connection factories).</para>
|
||
<section>
|
||
<title>JMS Server Management</title>
|
||
<para>JMS Resources (connection factories and destinations) can be created using the
|
||
<literal>JMSServerControl</literal> class (with the ObjectName <literal
|
||
>org.apache.activemq6:module=JMS,type=Server</literal> or the resource name <literal
|
||
>jms.server</literal>).</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Listing, creating, destroying connection factories</para>
|
||
<para>Names of the deployed connection factories can be retrieved by the <literal
|
||
>getConnectionFactoryNames()</literal> method.</para>
|
||
<para>JMS connection factories can be created or destroyed using the <literal
|
||
>createConnectionFactory()</literal> methods or <literal
|
||
>destroyConnectionFactory()</literal> methods. These connection factories
|
||
are bound to JNDI so that JMS clients can look them up. If a graphical console
|
||
is used to create the connection factories, the transport parameters are
|
||
specified in the text field input as a comma-separated list of key=value (e.g.
|
||
<literal>key1=10, key2="value", key3=false</literal>). If there are multiple
|
||
transports defined, you need to enclose the key/value pairs between curly
|
||
braces. For example <literal>{key=10}, {key=20}</literal>. In that case, the
|
||
first <literal>key</literal> will be associated to the first transport
|
||
configuration and the second <literal>key</literal> will be associated to the
|
||
second transport configuration (see <xref linkend="configuring-transports"/>
|
||
for a list of the transport parameters)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Listing, creating, destroying queues</para>
|
||
<para>Names of the deployed JMS queues can be retrieved by the <literal
|
||
>getQueueNames()</literal> method.</para>
|
||
<para>JMS queues can be created or destroyed using the <literal
|
||
>createQueue()</literal> methods or <literal>destroyQueue()</literal>
|
||
methods. These queues are bound to JNDI so that JMS clients can look them
|
||
up</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Listing, creating/destroying topics</para>
|
||
<para>Names of the deployed topics can be retrieved by the <literal
|
||
>getTopicNames()</literal> method.</para>
|
||
<para>JMS topics can be created or destroyed using the <literal
|
||
>createTopic()</literal> or <literal>destroyTopic()</literal> methods. These
|
||
topics are bound to JNDI so that JMS clients can look them up</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Listing and closing remote connections</para>
|
||
<para>JMS Clients remote addresses can be retrieved using <literal
|
||
>listRemoteAddresses()</literal>. It is also possible to close the
|
||
connections associated with a remote address using the <literal
|
||
>closeConnectionsForAddress()</literal> method.</para>
|
||
<para>Alternatively, connection IDs can be listed using <literal
|
||
>listConnectionIDs()</literal> and all the sessions for a given connection
|
||
ID can be listed using <literal>listSessions()</literal>.</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>JMS ConnectionFactory Management</title>
|
||
<para>JMS Connection Factories can be managed using the <literal
|
||
>ConnectionFactoryControl</literal> class (with the ObjectName <literal
|
||
>org.apache.activemq6:module=JMS,type=ConnectionFactory,name="<the connection factory
|
||
name>"</literal> or the resource name <literal>jms.connectionfactory.<the
|
||
connection factory name></literal>).</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Retrieving connection factory attributes</para>
|
||
<para>The <literal>ConnectionFactoryControl</literal> exposes JMS
|
||
ConnectionFactory configuration through its attributes (e.g. <literal
|
||
>getConsumerWindowSize()</literal> to retrieve the consumer window size for
|
||
flow control, <literal>isBlockOnNonDurableSend()</literal> to know whether the
|
||
producers created from the connection factory will block or not when sending
|
||
non-durable messages, etc.)</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>JMS Queue Management</title>
|
||
<para>JMS queues can be managed using the <literal>JMSQueueControl</literal> class (with
|
||
the ObjectName <literal>org.apache.activemq6:module=JMS,type=Queue,name="<the queue
|
||
name>"</literal> or the resource name <literal>jms.queue.<the queue
|
||
name></literal>). </para>
|
||
<para><emphasis>The management operations on a JMS queue are very similar to the
|
||
operations on a core queue. </emphasis></para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Expiring, sending to a dead letter address and moving messages</para>
|
||
<para>Messages can be expired from a queue by using the <literal
|
||
>expireMessages()</literal> method. If an expiry address is defined,
|
||
messages will be sent to it, otherwise they are discarded. The queue's
|
||
expiry address can be set with the <literal>setExpiryAddress()</literal>
|
||
method.</para>
|
||
<para>Messages can also be sent to a dead letter address with the <literal
|
||
>sendMessagesToDeadLetterAddress()</literal> method. It returns the number
|
||
of messages which are sent to the dead letter address. If a dead letter address
|
||
is not defined, message are removed from the queue and discarded. The queue's
|
||
dead letter address can be set with the <literal
|
||
>setDeadLetterAddress()</literal> method.</para>
|
||
<para>Messages can also be moved from a queue to another queue by using the
|
||
<literal>moveMessages()</literal> method.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Listing and removing messages</para>
|
||
<para>Messages can be listed from a queue by using the <literal
|
||
>listMessages()</literal> method which returns an array of <literal
|
||
>Map</literal>, one <literal>Map</literal> for each message.</para>
|
||
<para>Messages can also be removed from the queue by using the <literal
|
||
>removeMessages()</literal> method which returns a <literal
|
||
>boolean</literal> for the single message ID variant or the number of
|
||
removed messages for the filter variant. The <literal
|
||
>removeMessages()</literal> method takes a <literal>filter</literal>
|
||
argument to remove only filtered messages. Setting the filter to an empty
|
||
string will in effect remove all messages.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Counting messages</para>
|
||
<para>The number of messages in a queue is returned by the <literal
|
||
>getMessageCount()</literal> method. Alternatively, the <literal
|
||
>countMessages()</literal> will return the number of messages in the queue
|
||
which <emphasis>match a given filter</emphasis></para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Changing message priority</para>
|
||
<para>The message priority can be changed by using the <literal
|
||
>changeMessagesPriority()</literal> method which returns a <literal
|
||
>boolean</literal> for the single message ID variant or the number of
|
||
updated messages for the filter variant.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Message counters</para>
|
||
<para>Message counters can be listed for a queue with the <literal
|
||
>listMessageCounter()</literal> and <literal
|
||
>listMessageCounterHistory()</literal> methods (see <xref
|
||
linkend="management.message-counters"/>)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Retrieving the queue attributes</para>
|
||
<para>The <literal>JMSQueueControl</literal> exposes JMS queue settings through
|
||
its attributes (e.g. <literal>isTemporary()</literal> to know whether the queue
|
||
is temporary or not, <literal>isDurable()</literal> to know whether the queue is
|
||
durable or not, etc.)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Pausing and resuming queues</para>
|
||
<para>The <literal>JMSQueueControl</literal> can pause and resume the underlying
|
||
queue. When the queue is paused it will continue to receive messages but will
|
||
not deliver them. When resumed again it will deliver the enqueued messages, if
|
||
any. </para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>JMS Topic Management</title>
|
||
<para>JMS Topics can be managed using the <literal>TopicControl</literal> class (with
|
||
the ObjectName <literal>org.apache.activemq6:module=JMS,type=Topic,name="<the topic
|
||
name>"</literal> or the resource name <literal>jms.topic.<the topic
|
||
name></literal>).</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Listing subscriptions and messages</para>
|
||
<para>JMS topics subscriptions can be listed using the <literal
|
||
>listAllSubscriptions()</literal>, <literal
|
||
>listDurableSubscriptions()</literal>, <literal
|
||
>listNonDurableSubscriptions()</literal> methods. These methods return
|
||
arrays of <literal>Object</literal> representing the subscriptions information
|
||
(subscription name, client ID, durability, message count, etc.). It is also
|
||
possible to list the JMS messages for a given subscription with the <literal
|
||
>listMessagesForSubscription()</literal> method.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Dropping subscriptions</para>
|
||
<para>Durable subscriptions can be dropped from the topic using the <literal
|
||
>dropDurableSubscription()</literal> method.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Counting subscriptions messages</para>
|
||
<para>The <literal>countMessagesForSubscription()</literal> method can be used to
|
||
know the number of messages held for a given subscription (with an optional
|
||
message selector to know the number of messages matching the selector)</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
</section>
|
||
</section>
|
||
<section id="management.jmx">
|
||
<title>Using Management Via JMX</title>
|
||
<para>HornetQ can be managed using <ulink
|
||
url="http://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html"
|
||
>JMX</ulink>. </para>
|
||
<para>The management API is exposed by HornetQ using MBeans interfaces. HornetQ registers its
|
||
resources with the domain <literal>org.apache.activemq6</literal>.</para>
|
||
<para>For example, the <literal>ObjectName</literal> to manage a JMS Queue <literal
|
||
>exampleQueue</literal> is:</para>
|
||
<programlisting>
|
||
org.apache.activemq6:module=JMS,type=Queue,name="exampleQueue"</programlisting>
|
||
<para>and the MBean is:</para>
|
||
<programlisting>
|
||
org.apache.activemq6.api.jms.management.JMSQueueControl</programlisting>
|
||
<para>The MBean's <literal>ObjectName</literal> are built using the helper class <literal
|
||
>org.apache.activemq6.api.core.management.ObjectNameBuilder</literal>. You can also use <literal
|
||
>jconsole</literal> to find the <literal>ObjectName</literal> of the MBeans you want to
|
||
manage. </para>
|
||
<para>Managing HornetQ using JMX is identical to management of any Java Applications using
|
||
JMX. It can be done by reflection or by creating proxies of the MBeans.</para>
|
||
<section id="management.jmx.configuration">
|
||
<title>Configuring JMX</title>
|
||
<para>By default, JMX is enabled to manage HornetQ. It can be disabled by setting <literal
|
||
>jmx-management-enabled</literal> to <literal>false</literal> in <literal
|
||
>hornetq-configuration.xml</literal>:</para>
|
||
<programlisting>
|
||
<!-- false to disable JMX management for HornetQ -->
|
||
<jmx-management-enabled>false</jmx-management-enabled></programlisting>
|
||
<para>If JMX is enabled, HornetQ can be managed locally using <literal>jconsole</literal>.</para>
|
||
<note>
|
||
<para>Remote connections to JMX are not enabled by default for security reasons. Please refer
|
||
to <ulink url="http://docs.oracle.com/javase/6/docs/technotes/guides/management/agent.html"
|
||
>Java Management guide</ulink> to configure the server for remote management (system
|
||
properties must be set in <literal>run.sh</literal> or <literal>run.bat</literal>
|
||
scripts).</para>
|
||
</note>
|
||
<para>By default, HornetQ server uses the JMX domain "org.apache.activemq6". To manage several
|
||
HornetQ servers from the <emphasis>same</emphasis> MBeanServer, the JMX domain can be
|
||
configured for each individual HornetQ server by setting <literal>jmx-domain</literal>
|
||
in <literal>hornetq-configuration.xml</literal>: </para>
|
||
<programlisting>
|
||
<!-- use a specific JMX domain for HornetQ MBeans -->
|
||
<jmx-domain>my.org.apache.activemq6</jmx-domain></programlisting>
|
||
<section>
|
||
<title>MBeanServer configuration</title>
|
||
<para>When HornetQ is run in standalone, it uses the Java Virtual Machine's <literal
|
||
>Platform MBeanServer</literal> to register its MBeans. This is configured in
|
||
JBoss Microcontainer Beans file (see <xref
|
||
linkend="server.microcontainer.configuration"/>):</para>
|
||
<programlisting>
|
||
<!-- MBeanServer -->
|
||
<bean name="MBeanServer" class="javax.management.MBeanServer">
|
||
<constructor factoryClass="java.lang.management.ManagementFactory"
|
||
factoryMethod="getPlatformMBeanServer" />
|
||
</bean></programlisting>
|
||
<para>When it is integrated in JBoss AS 5+, it uses the Application Server's own MBean
|
||
Server so that it can be managed using AS 5's jmx-console:</para>
|
||
<programlisting>
|
||
<!-- MBeanServer -->
|
||
<bean name="MBeanServer" class="javax.management.MBeanServer">
|
||
<constructor factoryClass="org.jboss.mx.util.MBeanServerLocator"
|
||
factoryMethod="locateJBoss" />
|
||
</bean></programlisting>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>Example</title>
|
||
<para>See <xref linkend="examples.jmx"/> for an example which shows how to use a remote
|
||
connection to JMX and MBean proxies to manage HornetQ.</para>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>Using Management Via Core API</title>
|
||
<para>The core management API in HornetQ is called by sending Core messages to a special
|
||
address, the <emphasis>management address</emphasis>.</para>
|
||
<para><emphasis>Management messages</emphasis> are regular Core messages with well-known
|
||
properties that the server needs to understand to interact with the management API:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>The name of the managed resource</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The name of the management operation</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The parameters of the management operation</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>When such a management message is sent to the management address, HornetQ server will
|
||
handle it, extract the information, invoke the operation on the managed resources and send
|
||
a <emphasis>management reply</emphasis> to the management message's reply-to address
|
||
(specified by <literal>ClientMessageImpl.REPLYTO_HEADER_NAME</literal>). </para>
|
||
<para>A <literal>ClientConsumer</literal> can be used to consume the management reply and
|
||
retrieve the result of the operation (if any) stored in the reply's body. For portability,
|
||
results are returned as a <ulink url="http://json.org">JSON</ulink> String rather than Java
|
||
Serialization (the <literal>org.apache.activemq6.api.core.management.ManagementHelper</literal> can
|
||
be used to convert the JSON string to Java objects).</para>
|
||
<para>These steps can be simplified to make it easier to invoke management operations using
|
||
Core messages:</para>
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>Create a <literal>ClientRequestor</literal> to send messages to the management
|
||
address and receive replies</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Create a <literal>ClientMessage</literal></para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Use the helper class <literal
|
||
>org.apache.activemq6.api.core.management.ManagementHelper</literal> to fill the message
|
||
with the management properties</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Send the message using the <literal>ClientRequestor</literal></para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Use the helper class <literal
|
||
>org.apache.activemq6.api.core.management.ManagementHelper</literal> to retrieve the
|
||
operation result from the management reply</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
<para>For example, to find out the number of messages in the core queue <literal
|
||
>exampleQueue</literal>:</para>
|
||
<programlisting>
|
||
ClientSession session = ...
|
||
ClientRequestor requestor = new ClientRequestor(session, "jms.queue.hornetq.management");
|
||
ClientMessage message = session.createMessage(false);
|
||
ManagementHelper.putAttribute(message, "core.queue.exampleQueue", "messageCount");
|
||
session.start();
|
||
ClientMessage reply = requestor.request(m);
|
||
int count = (Integer) ManagementHelper.getResult(reply);
|
||
System.out.println("There are " + count + " messages in exampleQueue");</programlisting>
|
||
<para>Management operation name and parameters must conform to the Java interfaces defined in
|
||
the <literal>management</literal> packages.</para>
|
||
<para>Names of the resources are built using the helper class <literal
|
||
>org.apache.activemq6.api.core.management.ResourceNames</literal> and are straightforward
|
||
(<literal>core.queue.exampleQueue</literal> for the Core Queue <literal
|
||
>exampleQueue</literal>, <literal>jms.topic.exampleTopic</literal> for the JMS Topic
|
||
<literal>exampleTopic</literal>, etc.).</para>
|
||
<section id="management.core.configuration">
|
||
<title>Configuring Core Management</title>
|
||
<para>The management address to send management messages is configured in <literal
|
||
>hornetq-configuration.xml</literal>:</para>
|
||
<programlisting>
|
||
<management-address>jms.queue.hornetq.management</management-address></programlisting>
|
||
<para>By default, the address is <literal>jms.queue.hornetq.management</literal> (it is
|
||
prepended by "jms.queue" so that JMS clients can also send management messages).</para>
|
||
<para>The management address requires a <emphasis>special</emphasis> user permission
|
||
<literal>manage</literal> to be able to receive and handle management messages. This
|
||
is also configured in hornetq-configuration.xml:</para>
|
||
<programlisting>
|
||
<!-- users with the admin role will be allowed to manage -->
|
||
<!-- HornetQ using management messages -->
|
||
<security-setting match="jms.queue.hornetq.management">
|
||
<permission type="manage" roles="admin" />
|
||
</security-setting></programlisting>
|
||
</section>
|
||
</section>
|
||
<section id="management.jms">
|
||
<title>Using Management Via JMS</title>
|
||
<para>Using JMS messages to manage HornetQ is very similar to using core API.</para>
|
||
<para>An important difference is that JMS requires a JMS queue to send the messages to
|
||
(instead of an address for the core API).</para>
|
||
<para>The <emphasis>management queue</emphasis> is a special queue and needs to be
|
||
instantiated directly by the client:</para>
|
||
<programlisting>
|
||
Queue managementQueue = HornetQJMSClient.createQueue("hornetq.management");</programlisting>
|
||
<para>All the other steps are the same than for the Core API but they use JMS API
|
||
instead:</para>
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>create a <literal>QueueRequestor</literal> to send messages to the management
|
||
address and receive replies</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>create a <literal>Message</literal></para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>use the helper class <literal
|
||
>org.apache.activemq6.api.jms.management.JMSManagementHelper</literal> to fill the message
|
||
with the management properties</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>send the message using the <literal>QueueRequestor</literal></para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>use the helper class <literal
|
||
>org.apache.activemq6.api.jms.management.JMSManagementHelper</literal> to retrieve the
|
||
operation result from the management reply</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
<para>For example, to know the number of messages in the JMS queue <literal
|
||
>exampleQueue</literal>:</para>
|
||
<programlisting>
|
||
Queue managementQueue = HornetQJMSClient.createQueue("hornetq.management");
|
||
|
||
QueueSession session = ...
|
||
QueueRequestor requestor = new QueueRequestor(session, managementQueue);
|
||
connection.start();
|
||
Message message = session.createMessage();
|
||
JMSManagementHelper.putAttribute(message, "jms.queue.exampleQueue", "messageCount");
|
||
Message reply = requestor.request(message);
|
||
int count = (Integer)JMSManagementHelper.getResult(reply);
|
||
System.out.println("There are " + count + " messages in exampleQueue");</programlisting>
|
||
<section>
|
||
<title>Configuring JMS Management</title>
|
||
<para>Whether JMS or the core API is used for management, the configuration steps are the
|
||
same (see <xref linkend="management.core.configuration"/>).</para>
|
||
</section>
|
||
<section>
|
||
<title>Example</title>
|
||
<para>See <xref linkend="examples.management"/> for an example which shows how to use JMS
|
||
messages to manage HornetQ server.</para>
|
||
</section>
|
||
</section>
|
||
|
||
<section id="management.notifications">
|
||
<title>Management Notifications</title>
|
||
<para>HornetQ emits <emphasis>notifications</emphasis> to inform listeners of potentially
|
||
interesting events (creation of new resources, security violation, etc.).</para>
|
||
<para>These notifications can be received by 3 different ways:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>JMX notifications</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Core messages</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>JMS messages</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<section>
|
||
<title>JMX Notifications</title>
|
||
<para>If JMX is enabled (see <xref linkend="management.jmx.configuration"/>), JMX
|
||
notifications can be received by subscribing to 2 MBeans:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>org.apache.activemq6:module=Core,type=Server</literal> for notifications on
|
||
<emphasis>Core</emphasis> resources</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>org.apache.activemq6:module=JMS,type=Server</literal> for notifications on
|
||
<emphasis>JMS</emphasis> resources</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>Core Messages Notifications</title>
|
||
<para>HornetQ defines a special <emphasis>management notification address</emphasis>. Core
|
||
queues can be bound to this address so that clients will receive management
|
||
notifications as Core messages</para>
|
||
<para>A Core client which wants to receive management notifications must create a core
|
||
queue bound to the management notification address. It can then receive the
|
||
notifications from its queue.</para>
|
||
<para>Notifications messages are regular core messages with additional properties
|
||
corresponding to the notification (its type, when it occurred, the resources which were
|
||
concerned, etc.).</para>
|
||
<para>Since notifications are regular core messages, it is possible to use message
|
||
selectors to filter out notifications and receives only a subset of all the
|
||
notifications emitted by the server.</para>
|
||
<section id="management.notifications.core.configuration">
|
||
<title>Configuring The Core Management Notification Address</title>
|
||
<para>The management notification address to receive management notifications is
|
||
configured in <literal>hornetq-configuration.xml</literal>:</para>
|
||
<programlisting>
|
||
<management-notification-address>hornetq.notifications</management-notification-address></programlisting>
|
||
<para>By default, the address is <literal>hornetq.notifications</literal>.</para>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>JMS Messages Notifications</title>
|
||
<para>HornetQ's notifications can also be received using JMS messages.</para>
|
||
<para>It is similar to receiving notifications using Core API but an important difference
|
||
is that JMS requires a JMS Destination to receive the messages (preferably a
|
||
Topic).</para>
|
||
<para>To use a JMS Destination to receive management notifications, you must change the server's
|
||
management notification address to start with <literal>jms.queue</literal> if it is a JMS Queue
|
||
or <literal>jms.topic</literal> if it is a JMS Topic:</para>
|
||
<programlisting>
|
||
<!-- notifications will be consumed from "notificationsTopic" JMS Topic -->
|
||
<management-notification-address>jms.topic.notificationsTopic</management-notification-address></programlisting>
|
||
<para>Once the notification topic is created, you can receive messages from it or set a
|
||
<literal>MessageListener</literal>:</para>
|
||
<programlisting>
|
||
Topic notificationsTopic = HornetQJMSClient.createTopic("notificationsTopic");
|
||
|
||
Session session = ...
|
||
MessageConsumer notificationConsumer = session.createConsumer(notificationsTopic);
|
||
notificationConsumer.setMessageListener(new MessageListener()
|
||
{
|
||
public void onMessage(Message notif)
|
||
{
|
||
System.out.println("------------------------");
|
||
System.out.println("Received notification:");
|
||
try
|
||
{
|
||
Enumeration propertyNames = notif.getPropertyNames();
|
||
while (propertyNames.hasMoreElements())
|
||
{
|
||
String propertyName = (String)propertyNames.nextElement();
|
||
System.out.format(" %s: %s\n", propertyName, notif.getObjectProperty(propertyName));
|
||
}
|
||
}
|
||
catch (JMSException e)
|
||
{
|
||
}
|
||
System.out.println("------------------------");
|
||
}
|
||
});</programlisting>
|
||
</section>
|
||
<section>
|
||
<title>Example</title>
|
||
<para>See <xref linkend="examples.management-notifications"/> for an example which shows
|
||
how to use a JMS <literal>MessageListener</literal> to receive management notifications
|
||
from HornetQ server.</para>
|
||
</section>
|
||
<section id="notification.types.and.headers">
|
||
<title>Notification Types and Headers</title>
|
||
<para>Below is a list of all the different kinds of notifications as well as which headers are
|
||
on the messages. Every notification has a <literal>_HQ_NotifType</literal> (value noted in parentheses)
|
||
and <literal>_HQ_NotifTimestamp</literal> header. The timestamp is the un-formatted result of a call
|
||
to <literal>java.lang.System.currentTimeMillis()</literal>.</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>BINDING_ADDED</literal> (0)</para>
|
||
<para><literal>_HQ_Binding_Type</literal>, <literal>_HQ_Address</literal>,
|
||
<literal>_HQ_ClusterName</literal>, <literal>_HQ_RoutingName</literal>,
|
||
<literal>_HQ_Binding_ID</literal>, <literal>_HQ_Distance</literal>,
|
||
<literal>_HQ_FilterString</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>BINDING_REMOVED</literal> (1)</para>
|
||
<para><literal>_HQ_Address</literal>, <literal>_HQ_ClusterName</literal>,
|
||
<literal>_HQ_RoutingName</literal>, <literal>_HQ_Binding_ID</literal>,
|
||
<literal>_HQ_Distance</literal>, <literal>_HQ_FilterString</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>CONSUMER_CREATED</literal> (2)</para>
|
||
<para><literal>_HQ_Address</literal>, <literal>_HQ_ClusterName</literal>,
|
||
<literal>_HQ_RoutingName</literal>, <literal>_HQ_Distance</literal>,
|
||
<literal>_HQ_ConsumerCount</literal>, <literal>_HQ_User</literal>,
|
||
<literal>_HQ_RemoteAddress</literal>, <literal>_HQ_SessionName</literal>,
|
||
<literal>_HQ_FilterString</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>CONSUMER_CLOSED</literal> (3)</para>
|
||
<para><literal>_HQ_Address</literal>, <literal>_HQ_ClusterName</literal>,
|
||
<literal>_HQ_RoutingName</literal>, <literal>_HQ_Distance</literal>,
|
||
<literal>_HQ_ConsumerCount</literal>, <literal>_HQ_User</literal>,
|
||
<literal>_HQ_RemoteAddress</literal>, <literal>_HQ_SessionName</literal>,
|
||
<literal>_HQ_FilterString</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>SECURITY_AUTHENTICATION_VIOLATION</literal> (6)</para>
|
||
<para><literal>_HQ_User</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>SECURITY_PERMISSION_VIOLATION</literal> (7)</para>
|
||
<para><literal>_HQ_Address</literal>, <literal>_HQ_CheckType</literal>,
|
||
<literal>_HQ_User</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>DISCOVERY_GROUP_STARTED</literal> (8)</para>
|
||
<para><literal>name</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>DISCOVERY_GROUP_STOPPED</literal> (9)</para>
|
||
<para><literal>name</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>BROADCAST_GROUP_STARTED</literal> (10)</para>
|
||
<para><literal>name</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>BROADCAST_GROUP_STOPPED</literal> (11)</para>
|
||
<para><literal>name</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>BRIDGE_STARTED</literal> (12)</para>
|
||
<para><literal>name</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>BRIDGE_STOPPED</literal> (13)</para>
|
||
<para><literal>name</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>CLUSTER_CONNECTION_STARTED</literal> (14)</para>
|
||
<para><literal>name</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>CLUSTER_CONNECTION_STOPPED</literal> (15)</para>
|
||
<para><literal>name</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>ACCEPTOR_STARTED</literal> (16)</para>
|
||
<para><literal>factory</literal>, <literal>id</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>ACCEPTOR_STOPPED</literal> (17)</para>
|
||
<para><literal>factory</literal>, <literal>id</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>PROPOSAL</literal> (18)</para>
|
||
<para><literal>_JBM_ProposalGroupId</literal>, <literal>_JBM_ProposalValue</literal>,
|
||
<literal>_HQ_Binding_Type</literal>, <literal>_HQ_Address</literal>,
|
||
<literal>_HQ_Distance</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>PROPOSAL_RESPONSE</literal> (19)</para>
|
||
<para><literal>_JBM_ProposalGroupId</literal>, <literal>_JBM_ProposalValue</literal>,
|
||
<literal>_JBM_ProposalAltValue</literal>, <literal>_HQ_Binding_Type</literal>,
|
||
<literal>_HQ_Address</literal>, <literal>_HQ_Distance</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>CONSUMER_SLOW</literal> (21)</para>
|
||
<para><literal>_HQ_Address</literal>, <literal>_HQ_ConsumerCount</literal>,
|
||
<literal>_HQ_RemoteAddress</literal>, <literal>_HQ_ConnectionName</literal>,
|
||
<literal>_HQ_ConsumerName</literal>, <literal>_HQ_SessionName</literal></para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
</section>
|
||
<section id="management.message-counters">
|
||
<title>Message Counters</title>
|
||
<para>Message counters can be used to obtain information on queues <emphasis>over
|
||
time</emphasis> as HornetQ keeps a history on queue metrics.</para>
|
||
<para>They can be used to show <emphasis>trends</emphasis> on queues. For example, using the
|
||
management API, it would be possible to query the number of messages in a queue at regular
|
||
interval. However, this would not be enough to know if the queue is used: the number of
|
||
messages can remain constant because nobody is sending or receiving messages from the queue
|
||
or because there are as many messages sent to the queue than messages consumed from it. The
|
||
number of messages in the queue remains the same in both cases but its use is widely
|
||
different.</para>
|
||
<para>Message counters gives additional information about the queues:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>count</literal></para>
|
||
<para>The <emphasis>total</emphasis> number of messages added to the queue since the
|
||
server was started</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>countDelta</literal></para>
|
||
<para>the number of messages added to the queue <emphasis>since the last message counter
|
||
update</emphasis></para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>messageCount</literal></para>
|
||
<para>The <emphasis>current</emphasis> number of messages in the queue</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>messageCountDelta</literal></para>
|
||
<para>The <emphasis>overall</emphasis> number of messages added/removed from the queue
|
||
<emphasis>since the last message counter update</emphasis>. For example, if
|
||
<literal>messageCountDelta</literal> is equal to <literal>-10</literal> this means that
|
||
overall 10 messages have been removed from the queue (e.g. 2 messages were added and
|
||
12 were removed)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>lastAddTimestamp</literal></para>
|
||
<para>The timestamp of the last time a message was added to the queue</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>udpateTimestamp</literal></para>
|
||
<para>The timestamp of the last message counter update</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>These attributes can be used to determine other meaningful data as well. For example, to know
|
||
specifically how many messages were <emphasis>consumed</emphasis> from the queue since the last update
|
||
simply subtract the <literal>messageCountDelta</literal> from <literal>countDelta</literal>.</para>
|
||
<section id="configuring.message.counters">
|
||
<title>Configuring Message Counters</title>
|
||
<para>By default, message counters are disabled as it might have a small negative effect on
|
||
memory.</para>
|
||
<para>To enable message counters, you can set it to <literal>true</literal> in <literal
|
||
>hornetq-configuration.xml</literal>:</para>
|
||
<programlisting>
|
||
<message-counter-enabled>true</message-counter-enabled></programlisting>
|
||
<para>Message counters keeps a history of the queue metrics (10 days by default) and
|
||
samples all the queues at regular interval (10 seconds by default). If message counters
|
||
are enabled, these values should be configured to suit your messaging use case in
|
||
<literal>hornetq-configuration.xml</literal>:</para>
|
||
<programlisting>
|
||
<!-- keep history for a week -->
|
||
<message-counter-max-day-history>7</message-counter-max-day-history>
|
||
<!-- sample the queues every minute (60000ms) -->
|
||
<message-counter-sample-period>60000</message-counter-sample-period></programlisting>
|
||
<para>Message counters can be retrieved using the Management API. For example, to retrieve
|
||
message counters on a JMS Queue using JMX:</para>
|
||
<programlisting>
|
||
// retrieve a connection to HornetQ's MBeanServer
|
||
MBeanServerConnection mbsc = ...
|
||
JMSQueueControlMBean queueControl = (JMSQueueControl)MBeanServerInvocationHandler.newProxyInstance(mbsc,
|
||
on,
|
||
JMSQueueControl.class,
|
||
false);
|
||
// message counters are retrieved as a JSON String
|
||
String counters = queueControl.listMessageCounter();
|
||
// use the MessageCounterInfo helper class to manipulate message counters more easily
|
||
MessageCounterInfo messageCounter = MessageCounterInfo.fromJSON(counters);
|
||
System.out.format("%s message(s) in the queue (since last sample: %s)\n",
|
||
messageCounter.getMessageCount(),
|
||
messageCounter.getMessageCountDelta());</programlisting>
|
||
</section>
|
||
<section>
|
||
<title>Example</title>
|
||
<para>See <xref linkend="examples.message-counters"/> for an example which shows how to use
|
||
message counters to retrieve information on a JMS <literal>Queue</literal>.</para>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>Administering HornetQ Resources Using The JBoss AS Admin Console</title>
|
||
<para>Its possible to create and configure HornetQ resources via the admin console within the JBoss Application Server.</para>
|
||
<para>The Admin Console will allow you to create destinations (JMS Topics and Queues) and JMS Connection Factories.</para>
|
||
<para>Once logged in to the admin console you will see a JMS Manager item in the left hand tree. All HornetQ resources
|
||
will be configured via this. This will have a child items for JMS Queues, Topics and Connection Factories, clicking
|
||
on each node will reveal which resources are currently available. The following sections explain how to create
|
||
and configure each resource in turn.</para>
|
||
<section>
|
||
<title>JMS Queues</title>
|
||
<para>To create a new JMS Queue click on the JMS Queues item to reveal the available queues. On the right hand
|
||
panel you will see an add a new resource button, click on this and then choose the default(JMS Queue) template
|
||
and click continue. The important things to fill in here are the name of the queue and the JNDI name of the
|
||
queue. The JNDI name is what you will use to look up the queue in JNDI from your client. For most queues this
|
||
will be the only info you will need to provide as sensible defaults are provided for the others. You will also
|
||
see a security roles section near the bottom. If you do not provide any roles for this queue then the servers
|
||
default security configuration will be used, after you have created the queue these will be shown in the configuration.
|
||
All configuration values, except the name and JNDI name, can be changed via the configuration tab after clicking
|
||
on the queue in the admin console. The following section explains these in more detail</para>
|
||
<para>After highlighting the configuration you will see the following screen</para>
|
||
<para>
|
||
<graphic fileref="images/console1.png" scalefit="1" width="500" align="center"/>
|
||
</para>
|
||
<para>The name and JNDI name can't be changed, if you want to change these recreate the queue with the appropriate
|
||
settings. The rest of the configuration options, apart from security roles, relate to address settings for a particular
|
||
address. The default address settings are picked up from the servers configuration, if you change any of these
|
||
settings or create a queue via the console a new Address Settings entry will be added. For a full explanation on
|
||
Address Settings see <xref linkend="queue-attributes.address-settings"/></para>
|
||
<para>To delete a queue simply click on the delete button beside the queue name in the main JMS Queues screen.
|
||
This will also delete any address settings or security settings previously created for the queues address</para>
|
||
<para>The last part of the configuration options are security roles. If non are provided on creation then the
|
||
servers default security settings will be shown. If these are changed or updated then new security settings are
|
||
created for the address of this queue. For more information on security setting see <xref linkend="security"/> </para>
|
||
<para>It is also possible via the metrics tab to view statistics for this queue. This will show statistics such
|
||
as message count, consumer count etc.</para>
|
||
<para>Operations can be performed on a queue via the control tab. This will allow you to start and stop the queue,
|
||
list,move,expire and delete messages from the queue and other useful operations. To invoke an operation click on
|
||
the button for the operation you want, this will take you to a screen where you can parameters for the operation can be set.
|
||
Once set clicking the ok button will invoke the operation, results appear at the bottom of the screen.</para>
|
||
</section>
|
||
<section>
|
||
<title>JMS Topics</title>
|
||
<para>Creating and configuring JMS Topics is almost identical to creating queues. The only difference is that the
|
||
configuration will be applied to the queue representing a subscription.</para>
|
||
</section>
|
||
<section>
|
||
<title>JMS Connection Factories</title>
|
||
<para>The format for creating connection factories is the same as for JMS Queues and topics apart from the configuration
|
||
being different. For as list of all the connection factory settings see the configuration index </para>
|
||
</section>
|
||
</section>
|
||
</chapter>
|