806 lines
53 KiB
XML
806 lines
53 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. -->
|
||
<!-- ============================================================================= -->
|
||
<chapter id="management">
|
||
<title>管理</title>
|
||
<para>ActiveMQ拥有套丰富的管理接口。用户使用这些接口可以修改服务器配置、创建新的资源(如队列和
|
||
话题)、检查这些资源(如队列中有多少消息)并进行管理(从队列中删除消息)。这样用户可以
|
||
<emphasis>管理</emphasis>ActiveMQ。另外,客户还可以订阅管理通知。</para>
|
||
<para>有三种方式管理ActiveMQ:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>使用JMX -- JMX是标准的Java应用程序管理方式。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>使用核心接口 -- 管理操作通过<emphasis>核心消息</emphasis>的方法发向ActiveMQ服
|
||
务。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>使用JMS接口 -- 管理操作通过<emphasis>JMS消息</emphasis>的方式发向ActiveMQ服务器。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>虽然有三种方式,但它们提供相同的功能。使用JMX方法能完成的功能使用核心接口或JMS接口都可以完成。</para>
|
||
<para>根据不同的应用环境来选择最适当的方式。</para>
|
||
<section>
|
||
<title>管理接口API</title>
|
||
<para>不管使用哪种方式,管理接口都是一样的。</para>
|
||
<para>对于每个<emphasis>被管理的资源</emphasis>都有一个Java的接口提供可使用的操作。</para>
|
||
<para>ActiveMQ的管理接口分布在2个包中:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><emphasis>核心</emphasis>资源的管理接口在 <literal
|
||
>org.apache.activemq.api.core.management</literal>包中。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><emphasis>JMS</emphasis>资源的管理接口在 <literal
|
||
>org.apache.activemq.api.jms.management</literal>包中。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>调用<emphasis>管理操作</emphasis>的方法由所使用是方式是JMX、核心消息还是JMS
|
||
消息来决定。</para>
|
||
<note>
|
||
<para>一小部分的管理接口需要一个<literal>过滤器</literal>参数来选择需要的消息。
|
||
如果要求<emphasis>所有的消息</emphasis>,传递该参数时使用<literal>
|
||
null</literal>或者一个空的字符串即可。</para>
|
||
</note>
|
||
<section>
|
||
<title>核心管理接口</title>
|
||
<para>ActiveMQ定义了一套对核心资源的管理接口。关于它们的详细说明请参见相应的javadoc。
|
||
下面是对它们的概述:</para>
|
||
<section>
|
||
<title>核心服务器管理</title>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>队列的列表、创建、部署与删除</para>
|
||
<para><literal>getQueueNames()</literal> method方法用来列出所有已经部署的队列。</para>
|
||
<para>在<literal>ActiveMQServerControl</literal> (ObjectName <literal
|
||
>org.apache.activemq:module=Core,type=Server</literal>或资源名<literal
|
||
>core.server</literal>)上有队列创建或删除的方法,它们是
|
||
<literal>createQueue()</literal>、<literal>deployQueue()</literal>和
|
||
<literal>destroyQueue()</literal>。</para>
|
||
<para>如果队列已经存在,那么<literal>createQueue</literal>方法调用会出错,而
|
||
<literal>deployQueue</literal>方法调用没有任何作用。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>暂停与恢复队列</para>
|
||
<para><literal>QueueControl</literal>可用来暂停与恢复队列。如果一个队列被暂停,它
|
||
虽然可以继续接收消息但是不传递消息;当被恢复时,队列又会开始传递消息。
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>远程连接的列表与关闭</para>
|
||
<para><literal>listRemoteAddresses()</literal>方法可以用来列出客户端的远程地址。
|
||
还可以使用<literal>closeConnectionsForAddress()</literal>方法来关闭
|
||
与该地址相关的远程连接。</para>
|
||
<para>另外,使用<literal>listConnectionIDs()</literal>方法可以列出连接ID,
|
||
使用<literal>listSessions()</literal>方法可以列出与一个连接ID相关的所有
|
||
会话(session)。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>事务的手动操作(heuristic operations)</para>
|
||
<para>当服务器由于故障而重新启动时,可能造成一些事务没有完成而需要人工干预。
|
||
<literal>listPreparedTransactions()</literal>方法可以列出所有处于
|
||
准备(prepared)状态的事务(事务是用Base64字符串的形式列出)。如果要提交或回滚,
|
||
可以使用<literal>commitPreparedTransaction()</literal>方法或
|
||
<literal>rollbackPreparedTransaction()</literal>方法。采用启发式
|
||
(heuristic)完成的事务可以用<literal>listHeuristicCommittedTransactions()</literal>
|
||
方法和<literal>listHeuristicRolledBackTransactions</literal>方法列出。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>打开和重置消息计数器</para>
|
||
<para>消息计数器可以用<literal>enableMessageCounters()</literal>方法打开,用
|
||
<literal>disableMessageCounters()</literal>方法关闭。如果要重置消息计数器,
|
||
可以使用<literal>resetAllMessageCounters()</literal>方法和
|
||
<literal>resetAllMessageCounterHistories()</literal>方法。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>获得服务器的配置和属性</para>
|
||
<para><literal>ActiveMQServerControl</literal>提供了访问ActiveMQ服务器所有属性
|
||
的方法(例如<literal>getVersion()</literal>方法可以得到服务器的版本,等等)。 </para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>核心桥和转发器的创建,删除与列表</para>
|
||
<para>使用<literal>getBridgeNames()</literal>可以列出部署的核心桥。
|
||
使用<literal>getDivertNames()</literal>可以列出部署的转发器。</para>
|
||
<para>使用<literal>ActiveMQServerControl</literal> (ObjectName <literal
|
||
>org.apache.activemq:module=Core,type=Server</literal> 或资源名 <literal
|
||
>core.server</literal>)的方法<literal>createBridge()</literal>
|
||
和<literal>destroyBridge()</literal>可以创建和删除核心桥。
|
||
通过<literal>createDivert()</literal>和<literal>destroyDivert()</literal>
|
||
可以创建和删除转发器。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>核心地址的管理</title>
|
||
<para>核心地址可以通过<literal>AddressControl</literal>类进行访问(ObjectName
|
||
是 <literal>org.apache.activemq:module=Core,type=Address,name="<the
|
||
address name>"</literal>或者资源名 <literal>core.address.<the
|
||
address name></literal>)。</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>修改地址的角色和权限。</para>
|
||
<para>你可以使用<literal>addRole()</literal>方法或<literal>removeRole()</literal>
|
||
方法添加或删除地址的角色。用<literal>getRoles()</literal>方法可以列出一个地址的所有角色。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>核心队列的管理</title>
|
||
<para>管理接口中的一大部分是管理核心队列的。<literal>QueueControl</literal>类定义了核心队列的管理
|
||
接口(ObjectName <literal>org.apache.activemq:module=Core,type=Queue,address="<绑定地址
|
||
address>",name="<队列名>"</literal> 或资源名 <literal
|
||
>core.queue.<队列名></literal>)。</para>
|
||
<para>绝大部分的队列管理方法需要一个消息ID参数(如删除一个消息)或一个过滤器参数(如将具有某个
|
||
属性值的所有消息设置为过期)。</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>消息的过期,发向死信地址及删除</para>
|
||
<para><literal>expireMessages()</literal>方法可以使消息过期。如果设置了一个过期地址,
|
||
这些消息会被发到过期地址。否则这些消息会被丢弃。<literal>setExpiryAddress()</literal>
|
||
方法可以用来设置队列的过期地址。</para>
|
||
<para>消息可以用<literal>sendMessagesToDeadLetterAddress()</literal>方法发送到
|
||
一个死信地址。它返回发到这个死信地址的消息的数量。如果没有设置死信地址,那么消息就会从队列中
|
||
删除。用<literal>setDeadLetterAddress()</literal>方法可以设置队列的死信地址。</para>
|
||
<para>消息还可以从一个队列转移到另一个队列。其方法是
|
||
<literal>moveMessages()</literal>。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>消息的列表与删除</para>
|
||
<para>用<literal>listMessages()</literal>方法可以列出一个队列中的所有消息。这个方法
|
||
返回的是一个<literal>Map</literal>的数组。每一个Map对应一个消息。</para>
|
||
<para>消息可以用<literal>removeMessages()</literal>方法删除。如果是使用消息ID,
|
||
返回的是一个布尔常量;如果是用过滤器,则返回的
|
||
是删除的消息数量。在使用过滤器来删除过滤的消息时,如果传入一个空字符串则表示要删除
|
||
所有的消息。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>消息计数</para>
|
||
<para>一个队列中的消息数可以用<literal>getMessageCount()</literal>方法获得。
|
||
此外,<literal>countMessages()</literal>方法可以返回队列中与一
|
||
个<emphasis>过滤器</emphasis>匹配的消息数量。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>修改消息的优先级</para>
|
||
<para>用<literal>changeMessagesPriority()</literal>方法可以改变消息的优先级。
|
||
该方法如果带一个消息ID参数,返回一个布尔常量;如果带一个过滤器参数,返回优先级
|
||
被更新的消息的数量。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>消息计数器</para>
|
||
<para>用<literal>listMessageCounter()</literal>方法和<literal>
|
||
listMessageCounterHistory()</literal>方法可以列出一个队列的消息计数器。
|
||
(参见 <xref linkend="management.message-counters"/>)。消息计数器还可以
|
||
用<literal>resetMessageCounter()</literal>方法重置。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>获得队列的属性</para>
|
||
<para>通过<literal>QueueControl</literal>可以获得核心队列的属性(例如用
|
||
<literal>getFilter()</literal>方法可以得到队列的
|
||
过滤器,<literal>isDurable()</literal>方法可以知道队列是否是持久的队列等等)。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>暂停和恢复队列</para>
|
||
<para><literal>QueueControl</literal>可用来暂停与恢复队列。如果一个队列被暂停,它
|
||
虽然可以继续接收消息但是不传递消息;当被恢复时,队列又会开始传递消息。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>其它核心资源的管理</title>
|
||
<para>ActiveMQ允许用户启动或停止其远程资源(接收器,转发器,桥,等等)。这样可以使服务器暂停工作
|
||
而不需要完全停止服务器(比如可以临时对服务器进行一些离线操作,像对一些事务的处理)。这些资源有:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>接收器</para>
|
||
<para>用<literal>AcceptorControl</literal>类(ObjectName <literal
|
||
>org.apache.activemq:module=Core,type=Acceptor,name="<接收器名
|
||
>"</literal> 或资源名 <literal>core.acceptor.<地址名
|
||
></literal>)的<literal>start()</literal>方法启动,用<literal>
|
||
stop()</literal>方法停止。接收器的参数可以通过<literal>AcceptorControl</literal>
|
||
的属性获得。(参见 <xref
|
||
linkend="configuring-transports.acceptors"/>)。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>转发器</para>
|
||
<para>用<literal>DivertControl</literal>(ObjectName是 <literal
|
||
>org.apache.activemq:module=Core,type=Divert,name=<转发器名></literal>
|
||
或资源名<literal>core.divert.<转发器></literal>)类的
|
||
<literal>start()</literal>方法可以启动,用<literal>stop()</literal>方法可以停止。
|
||
通过<literal>DivertControl</literal>还可以获得转发器的各种属性。(参见 <xref
|
||
linkend="diverts"/>)。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>桥</para>
|
||
<para>桥可以通过<literal>BridgeControl</literal>类(ObjectName <literal
|
||
>org.apache.activemq:module=Core,type=Bridge,name="<桥的名字
|
||
>"</literal> 或资源名 <literal>core.bridge.<桥的名字
|
||
></literal>)的<literal>start()</literal>
|
||
方法启动,用<literal>stop()</literal>方法停止。它的属性可以通过
|
||
<literal>BridgeControl</literal>的属性获得(参见
|
||
<xref linkend="core-bridges"/>)。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>广播组</para>
|
||
<para>广播组可以通过<literal>BroadcastGroupControl</literal>类(ObjectName <literal
|
||
>org.apache.activemq:module=Core,type=BroadcastGroup,name="<广播组名
|
||
>"</literal> 或者资源名 <literal
|
||
>core.broadcastgroup.<广播组名></literal>)的<literal>
|
||
start()</literal>方法启动,用<literal>stop()</literal>方法停止。
|
||
它的属性也可以通过<literal
|
||
>BroadcastGroupControl</literal>的属性获得(参见<xref
|
||
linkend="clusters.broadcast-groups"/>)。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>发现组</para>
|
||
<para>发现组可以通过<literal>DiscoveryGroupControl</literal>类
|
||
(ObjectName <literal>org.apache.activemq:module=Core,type=DiscoveryGroup,
|
||
name="<发现组名>"</literal> 或资源名<literal>core.discovery.<
|
||
发现组名></literal>)的
|
||
<literal>start()</literal>方法启动,用<literal>stop()</literal>方法停止。
|
||
它的参数可以通过<literal>DiscoveryGroupControl</literal>的属性获得(参见
|
||
<xref linkend="clusters.discovery-groups"/>)。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>集群连接</para>
|
||
<para>集群连接可以通过<literal>ClusterConnectionControl</literal>类(
|
||
ObjectName <literal
|
||
>org.apache.activemq:module=Core,type=ClusterConnection,name="<集群连接名
|
||
>"</literal> 或资源名 <literal
|
||
>core.clusterconnection.<集群连接名></literal>)的<literal>
|
||
start()</literal>方法启动,用<literal>stop()</literal>方法停止。
|
||
它的参数可以通过<literal
|
||
>ClusterConnectionControl</literal>的属性来获得(参见
|
||
<xref linkend="clusters.cluster-connections"/>)。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>JMS管理接口</title>
|
||
<para>ActiveMQ定义了一套JMS管理接口来管理JMS的<emphasis>可管理的对象</emphasis>
|
||
(例如JMS队列,话题及连接工厂)。</para>
|
||
<section>
|
||
<title>JMS服务器管理</title>
|
||
<para><literal>JMSServerControl</literal>类(ObjectName <literal
|
||
>org.apache.activemq:module=JMS,type=Server</literal> 或资源名<literal
|
||
>jms.server</literal>)用来创建JMS资源(连接工厂和目标)。</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>列表、创建、删除连接工厂</para>
|
||
<para>使用<literal>getConnectionFactoryNames()</literal> 方法可以列出部署的连接工厂的
|
||
名字。</para>
|
||
<para>用<literal>createConnectionFactory()</literal>方法和<literal
|
||
>destroyConnectionFactory()</literal>方法能创建和删除JMS连接工厂。
|
||
这些连接工厂都与JNDI绑定以便于客户端来查找。如果是在图形介面下创建连接工厂,在广本框内输入
|
||
有关的传输参数时可使用一组用逗号隔开的键-值对(例如<literal>key1=10, key2="value", key3=false</literal>)。
|
||
如果需要定义多个传输,你需要将每个传输的参数对用大括号括起来,例如<literal>{key=10}, {key=20}</literal>。
|
||
第一个<literal>key</literal>属于第一个传输配置,第二个<literal>key</literal>属于第二个传输配置。
|
||
(有关传输的各种参数参见<xref linkend="configuring-transports"/>)。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>列表、创建与删除队列</para>
|
||
<para><literal>getQueueNames()</literal>方法可以获得部署的JMS队列的名字列表。</para>
|
||
<para>JMS队列可以用<literal>createQueue()</literal>方法创建,用<literal>destroyQueue()</literal>方法删除。
|
||
创建的队列都绑定到JNDI以便JMS客户端可以查找。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>列表、创建与删除话题(topic)</para>
|
||
<para><literal>getTopicNames()</literal>方法可以获得部署的JMS话题名字。</para>
|
||
<para>JMS话题可以用<literal>createTopic()</literal>方法来创建,用<literal>destroyTopic()</literal>方法来删除。
|
||
创建的话题都绑定到JNDI以便客户端查找。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>远程连接的列表与关闭</para>
|
||
<para>用<literal>listRemoteAddresses()</literal>方法可以获得JMS客户端的远程地址。
|
||
还可以用<literal>closeConnectionsForAddress()</literal>方法关闭与某个远程地址相关联的连接。</para>
|
||
<para>另外,<literal>listConnectionIDs()</literal>方法可以列出连接的ID,
|
||
而<literal>listSessions()</literal>方法可以列出一个给定的连接ID的所有会话(session)。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>JMS连接工厂的管理</title>
|
||
<para>使用类(ObjectName <literal>org.apache.activemq:module=JMS,type=ConnectionFactory,
|
||
name="<连接工厂名>"</literal>或者资源名<literal>jms.connectionfactory.<
|
||
连接工厂名></literal>)可以管理JMS的连接工厂。</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>获得连接工厂的属性</para>
|
||
<para><literal>ConnectionFactoryControl</literal>类可以用来获得连接工厂的属性(
|
||
例如<literal>getConsumerWindowSize()</literal>方法可以获得接收者流控制的窗口大小,
|
||
<literal>isBlockOnNonDurableSend()</literal>方法可以知道从这个连接工厂创建的发送
|
||
者是否采用阻塞方式发送非持久的消息,等等)。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>JMS队列管理</title>
|
||
<para>使用<literal>JMSQueueControl</literal>类(ObjectName <literal>org.apache.activemq:module=JMS,
|
||
type=Queue,name="<队列名>"</literal>或资源名 <literal>jms.queue.<队列名
|
||
></literal>可以管理JMS队列。</para>
|
||
<para><emphasis>JMS队列的管理操作与核心队列的管理十分相似。</emphasis></para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>过期,发送到死信地址和移动消息</para>
|
||
<para>可以使用<literal>expireMessages()</literal>方法将队列中的消息设成过期消息。
|
||
如果配置有过期地址,消息就会被发到过期地址。过期地址可以用
|
||
<literal>setExpiryAddress()</literal>方法来设定。</para>
|
||
<para>使用<literal>sendMessagesToDeadLetterAddress()</literal>方法可以将消息发送到死信地址。
|
||
它返回发送到死信地址消息的数量。如果没有设定死信地址,那么消息会被丢弃。使用
|
||
<literal>setDeadLetterAddress()</literal>方法可以设定队列的死信地址。</para>
|
||
<para><literal>moveMessages()</literal>方法将消息从一个队列移动到另一个队列。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>列表与删除消息</para>
|
||
<para>使用<literal>listMessages()</literal>方法可以列出一个队列中的所有消息。它返回的是一个
|
||
Map的数组。每一个Map对应一个消息。</para>
|
||
<para>使用<literal>removeMessages()</literal>方法可以从队列中删除消息。如果带的参数是消息ID,
|
||
返回的是一个布尔常是;如果带的参数是一个过滤器,则返回删除的消息数。带有过滤器参数的<literal
|
||
>removeMessages()</literal>方法只删除过滤器选择的消息。如果些参数是一个空字符串,那么将
|
||
删除所有的消息。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>消息计数</para>
|
||
<para>使用<literal>getMessageCount()</literal>方法可以得到队列中的消息数。另外,方法
|
||
<literal>countMessages()</literal>可以得到队列中所有与<emphasis>过滤器</emphasis>相匹配的消息数。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>修改消息的优先级</para>
|
||
<para>消息的优先级可以用<literal>changeMessagesPriority()</literal>方法修改。如果是带一个消
|
||
息ID参数,它返回的是一个布尔常量;如果是带一个过滤器参数,则它返回的是优先级更新了的消息数。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>消息计数器</para>
|
||
<para><literal>listMessageCounter()</literal>方法和<literal >listMessageCounterHistory()</literal>
|
||
方法可以用来列出队列中的所有消息计数器。(参见 <xref
|
||
linkend="management.message-counters"/>)。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>获取队列的属性</para>
|
||
<para><literal>JMSQueueControl</literal>类可以用来获取JMS队列的设置参数(例如方法<literal>isTemporary()</literal>
|
||
可以判断队列是否为临时的,方法<literal>isDurable()</literal>可以判断队列是否为持久的等等)。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>队列的暂停与恢复</para>
|
||
<para><literal>JMSQueueControl</literal>可以暂停一个队列或恢复一个队列。
|
||
如果一个队列被暂停,它虽然可以继续接收消息但是不传递消息;
|
||
当被恢复时,队列又会开始传递消息。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>JMS话题(Topic)的管理</title>
|
||
<para>JMS话题的管理是通过<literal>TopicControl</literal>类(
|
||
the ObjectName <literal>org.apache.activemq:module=JMS,type=Topic,name="<话题名>"</literal>
|
||
或资源名 <literal>jms.topic.<话题名></literal>)。</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>订阅和消息的列表</para>
|
||
<para><literal>listAllSubscriptions()</literal>、<literal
|
||
>listDurableSubscriptions()</literal>、 <literal
|
||
>listNonDurableSubscriptions()</literal>方法可以列出话题的不同订阅。
|
||
这些方法都返回<literal>Object</literal>数组,表示订阅的细节(如订阅名,
|
||
客户ID,持久性,消息计数等)。用<literal
|
||
>listMessagesForSubscription()</literal>方法可以列出一个订阅上的JMS消息。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>删除订阅</para>
|
||
<para>持久性订阅可以使用<literal>dropDurableSubscription()</literal>方法来删除。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>订阅消息计数</para>
|
||
<para><literal>countMessagesForSubscription()</literal>方法可以得到一个订阅上面所持有
|
||
的消息数(还可带一个消息选择器来得出有多少消息与之匹配)。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
</section>
|
||
</section>
|
||
<section id="management.jmx">
|
||
<title>使用JMX</title>
|
||
<para>ActiveMQ提供了<ulink
|
||
url="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/"
|
||
>JMX</ulink>。</para>
|
||
<para>ActiveMQ通过MBean的接口暴露其JMX管理操作。它将自己的资源注册到<literal>org.apache.activemq</literal>域。</para>
|
||
<para>比如,用来管理一个名为<literal>exampleQueue</literal>JMS队列的<literal>ObjectName</literal>是:</para>
|
||
<programlisting>
|
||
org.apache.activemq:module=JMS,type=Queue,name="exampleQueue"
|
||
</programlisting>
|
||
<para>MBean为:</para>
|
||
<programlisting>
|
||
org.apache.activemq.api.jms.management.JMSQueueControl
|
||
</programlisting>
|
||
<para>MBean的<literal>ObjectName</literal>用 <literal
|
||
>org.apache.activemq.api.core.management.ObjectNameBuilder</literal>来产生出来的。你也可以使用<literal
|
||
>jconsole</literal>来查找你想要的MBean的<literal>ObjectName</literal>。</para>
|
||
<para>使用JMX来管理ActiveMQ与用JMX管理其它Java应用程序没有什么不同。你可以使用反射或者创建MBean代理的方法。</para>
|
||
<section id="management.jmx.configuration">
|
||
<title>配置JMX</title>
|
||
<para>默认情况下ActiveMQ的JMX是打开的。将<literal
|
||
>activemq-configuration.xml</literal>文件中的<literal
|
||
>jmx-management-enabled</literal>设置为<literal>false</literal>就可以关闭JMX:</para>
|
||
<programlisting>
|
||
<!-- false to disable JMX management for ActiveMQ -->
|
||
<jmx-management-enabled>false</jmx-management-enabled>
|
||
</programlisting>
|
||
<para>如果JMX功能是打开的,则使用<literal>jconsole</literal>可以管理本地的ActiveMQ。</para>
|
||
<note>
|
||
<para>出于安全考虑,默认情况下JMX远程连接是关闭的。参见<ulink url="http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html#remote"
|
||
>Java管理指南</ulink>来配置服务器的远程管理(系统变量必须在<literal>run.sh</literal>或<literal>run.bat</literal>中定义)。</para>
|
||
</note>
|
||
<para>ActiveMQ默认使用JMX域名"org.apache.activemq"。如果要用一个MBeanServer管理多个ActiveMQ服务器,可以将每个ActiveMQ
|
||
服务器配置成不同的JMX域。方法就是在<literal>activemq-configuration.xml</literal>文件中设置<literal>jmx-domain</literal>:</para>
|
||
<programlisting>
|
||
<!-- use a specific JMX domain for ActiveMQ MBeans -->
|
||
<jmx-domain>my.org.apache.activemq</jmx-domain>
|
||
</programlisting>
|
||
<section>
|
||
<title>MBeanServer的配置</title>
|
||
<para>ActiveMQ在独立运行时使用Java虚拟机的<literal
|
||
>Platform MBeanServer</literal>来注册其MBean。这在JBoss Microcontainer(微容器)的bean
|
||
文件中进行配置(参见<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>当与AS 5+集成运行时,它使用应用服务器自己的MBean服务,这样就可以使用它的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>例子</title>
|
||
<para>参见<xref linkend="examples.jmx"/>,这个例子展示了如何使用远程JMX连接或MBean代理来管理ActiveMQ。</para>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>使用核心接口</title>
|
||
<para>核心管理接口的调用实际上是向一个特殊的地址发送核心消息。这个特殊地址称为<emphasis>管理地址</emphasis>。</para>
|
||
<para><emphasis>管理消息</emphasis>是一些定义了一些固定属性的普通核心消息。服务器通过这些属性来解释管理操作:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>管理资源的名称</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>管理操作的名称</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>管理操作的参数</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>当一个管理消息发送到管理地址时,ActiveMQ服务器将从中提取出相应的信息,再调用相应的管理资源的方法,之后向
|
||
该管理消息的回答地址(reply-to address,由<literal>ClientMessageImpl.REPLYTO_HEADER_NAME
|
||
</literal>定义)发送一个<emphasis>管理回答</emphasis>。</para>
|
||
<para>一个<literal>ClientConsumer</literal>用来接收管理回答并提取出其中的操作的結果(如果有的话)。
|
||
考虑到可移植性,返回的結果采用的是格式的字符串,而没有采用Java的序列化技术
|
||
(<literal>org.apache.activemq.api.core.management.ManagementHelper</literal>可以用来将JSON字符串
|
||
转换成Java对象)。</para>
|
||
<para>使用以下步骤可以简化使用核心消息调用管理操作:</para>
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>创建一个<literal>ClientRequestor</literal>对象,用来发送管理消息并接收回答。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>创建一个<literal>ClientMessage</literal>。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>使用<literal
|
||
>org.apache.activemq.api.core.management.ManagementHelper</literal>类来帮助设置消息的管理参数。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>通过<literal>ClientRequestor</literal>将消息发送</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>使用 <literal
|
||
>org.apache.activemq.api.core.management.ManagementHelper</literal>类从管理操作結果中提取返回值。</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
<para>例如,要得到核心队列<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");
|
||
ClientMessage reply = requestor.request(m);
|
||
int count = (Integer) ManagementHelper.getResult(reply);
|
||
System.out.println("There are " + count + " messages in exampleQueue");
|
||
</programlisting>
|
||
<para>管理操作名及其参数必须和<literal>management</literal>包中定义的Java接口一致。</para>
|
||
<para>资源的名称是用<literal>org.apache.activemq.api.core.management.ResourceNames</literal>类来生成的,
|
||
命名都非常直观(如核心队列<literal>exampleQueue</literal>的名称为<literal>core.queue.exampleQueue</literal>,
|
||
JMS Topic <literal>exampleTopic</literal>的名称为<literal>jms.topic.exampleTopic</literal>,等等)。
|
||
</para>
|
||
<section id="management.core.configuration">
|
||
<title>配置核心管理</title>
|
||
<para>管理地址的配置在文件<literal
|
||
>activemq-configuration.xml</literal>中:</para>
|
||
<programlisting>
|
||
<management-address>jms.queue.hornetq.management</management-address>
|
||
</programlisting>
|
||
<para>它的默认地址是<literal>jms.queue.hornetq.management</literal> (地址前缀加上
|
||
“jms.queue”是为了方便JMS客户端也可以向它发送管理消息。</para>
|
||
<para>管理地址需要一个<emphasis>特殊</emphasis>的用户权限
|
||
<literal>manage</literal>来接收并处理管理消息。这个权限也在hornetq-configuration.xml文件中配置:</para>
|
||
<programlisting>
|
||
<!-- users with the admin role will be allowed to manage -->
|
||
<!-- ActiveMQ 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>使用JMS进行管理</title>
|
||
<para>使用JMS管理ActiveMQ与使用核心API管理ActiveMQ十分相似。</para>
|
||
<para>其中一个重要的不同是JMS需要一个JMS队列来发送消息(而核心接口使用的是一个地址)。</para>
|
||
<para><emphasis>管理队列</emphasis>是一个特殊的队列,它需要客户端直接实例化:</para>
|
||
<programlisting>
|
||
Queue managementQueue = ActiveMQJMSClient.createQueue("hornetq.management");
|
||
</programlisting>
|
||
<para>其余步骤完全和使用核心接口一样,只是相应的对象不同:</para>
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>创建一个<literal>QueueRequestor</literal>来向管理地址发送管理消息并接收回答。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>创建一个<literal>消息</literal></para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>使用 <literal>org.apache.activemq.api.jms.management.JMSManagementHelper</literal>类向消息中设置管理参数。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>再使用<literal>QueueRequestor</literal>发送消息。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>使用<literal>org.apache.activemq.api.jms.management.JMSManagementHelper</literal>来从回答中提取返回結果。</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
<para>例如,要得到一个JMS队列<literal>exampleQueue</literal>中有多少消息:</para>
|
||
<programlisting>
|
||
Queue managementQueue = ActiveMQJMSClient.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>配置JMS管理</title>
|
||
<para>JMS管理的配置与核心接口管理的配置步骤是一样的(参见<xref linkend="management.core.configuration"/>)。</para>
|
||
</section>
|
||
<section>
|
||
<title>例子</title>
|
||
<para>参见<xref linkend="examples.management"/>,它展示了如何使用JMS消息来管理ActiveMQ。</para>
|
||
</section>
|
||
</section>
|
||
|
||
<section id="management.notifications">
|
||
<title>管理通知</title>
|
||
<para>ActiveMQ可以向listener发送各种事件的<emphasis>通知</emphasis>(如资源的创建,安全破坏等)。</para>
|
||
<para>有三种方式接收管理通知</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>JMX通知</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>核心消息</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>JMS消息</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<section>
|
||
<title>JMX通知</title>
|
||
<para>如果设置了JMX(参见<xref linkend="management.jmx.configuration"/>),就可以通过订阅以下
|
||
两个MBean来获得通知:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>org.apache.activemq:module=Core,type=Server</literal> 可以获得有关
|
||
<emphasis>核心</emphasis>资源的通知</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>org.apache.activemq:module=JMS,type=Server</literal>可以获得有关
|
||
<emphasis>JMS</emphasis>资源的通知</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>核心消息通知</title>
|
||
<para>ActiveMQ定义了一个特殊的<emphasis>管理通知地址</emphasis>。核心队列绑定到该地址后,客户
|
||
端就可以接收以核心消息形式发送的管理信通知了。</para>
|
||
<para>一个核心客户端要想接收到管理通知,它必须要创建一个队列并绑定到这个管理通知地址上,然后从这个
|
||
队列接收通知。</para>
|
||
<para>通知消息就是普通的核心消息加上相关的属性(如通知类型,事件发生时间,资源等)。</para>
|
||
<para>由于是标准的核心消息,使用选择器还能够过滤掉一部分通知而只接收感兴趣的通知。</para>
|
||
<section id="management.notifications.core.configuration">
|
||
<title>配置核心管理通知地址</title>
|
||
<para>用来发送管理通知的地址在文件中<literal>activemq-configuration.xml</literal>配置:</para>
|
||
<programlisting>
|
||
<management-notification-address>hornetq.notifications</management-notification-address>
|
||
</programlisting>
|
||
<para>默认的地址是<literal>hornetq.notifications</literal>。</para>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>JMS消息通知</title>
|
||
<para>ActiveMQ还可以通过JMS消息的方式发送通知。</para>
|
||
<para>这种方式与核心消息通知相似,但是有一个重要的不同:JMS消息需要一个JMS的目标(通常是一个Topic)。</para>
|
||
<para>要通过一个JMS目标来接收管理通知,必须将服务器的管理通知地址修改为以<literal>jms.queue</literal>开头(如果是一个
|
||
JMS队列)或者<literal>jms.topic</literal>(如果是一个话题):</para>
|
||
<programlisting>
|
||
<!-- 通知将从JMS话题 "notificationsTopic"上接收 -->
|
||
<management-notification-address>jms.topic.notificationsTopic</management-notification-address>
|
||
</programlisting>
|
||
<para>这个通知话题一旦被创建,就可以接收消息了(或者使用<literal>MessageListener</literal>):</para>
|
||
<programlisting>
|
||
Topic notificationsTopic = ActiveMQJMSClient.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>例子</title>
|
||
<para>参见<xref linkend="examples.management-notifications"/>。本例采用了JMS的<literal>
|
||
MessageListener</literal>方法从ActiveMQ
|
||
服务器接收管理通知。</para>
|
||
</section>
|
||
</section>
|
||
<section id="management.message-counters">
|
||
<title>消息计数器</title>
|
||
<para>ActiveMQ保存着队列的历史数据,而消息计数器可以从服务器上获取这些信息。</para>
|
||
<para>这些信息可以显示队列的一些<emphasis>趋势</emphasis>。例如,使用管理接口你可以定期来查询一个队列
|
||
的消息数量。但这个数量不足以说明这个队列是否在工作--也许这个队列既没有发送者也没有接收者;也许这个队列
|
||
在不停地发送与接收,但是发送消息的速度与接收的速度相等。两咱情况下都会造成消息数在队列中不变,但实际队列
|
||
的状态确完全不一样。</para>
|
||
<para>消息计数器可以提供队列的更多的信息:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>count</literal></para>
|
||
<para>从服务器启动时加到队列中的<emphasis>总</emphasis>消息数。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>countDelta</literal></para>
|
||
<para>自<emphasis>上次消息计数器更新</emphasis>后加入到队列的消息数。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>depth</literal></para>
|
||
<para>队列<emphasis>当前</emphasis>的消息数。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>depthDelta</literal></para>
|
||
<para>自<emphasis>上次消息计数器更新</emphasis>后被加入/删除的消息<emphasis>总数</emphasis>。
|
||
例如,如果<literal>depthDelta</literal>是<literal>-10</literal>,就意谓着有10个消息从
|
||
队列中删除了(有可能是2个消息加入了但有12个消息删除了)。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>lastAddTimestamp</literal></para>
|
||
<para>最后一个消息加入到队列的时间戳。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>udpateTimestamp</literal></para>
|
||
<para>最后一次消息计数器更新的时间戳。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<section id="configuring.message.counters">
|
||
<title>配置消息计数器</title>
|
||
<para>默认的消息计数器是关闭的,因为它需要占用一些内存。</para>
|
||
<para>要打开消息计数器,编辑<literal>activemq-configuration.xml</literal>文件将其设为<literal>true</literal>:</para>
|
||
<programlisting>
|
||
<message-counter-enabled>true</message-counter-enabled>
|
||
</programlisting>
|
||
<para>消息计数器会保存队列的历史数据(默认是10天)。它以一定间隔(默认10秒一次)对每个队列进行扫描。
|
||
如果消息计数器打开,这些参数可以在<literal>activemq-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>使用管理接口可以获得消息计数器。例如要使用JMX得到一个JMS队列的消息计数器:</para>
|
||
<programlisting>
|
||
// retrieve a connection to ActiveMQ'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",
|
||
counter.getDepth(),
|
||
counter.getDepthDelta());
|
||
</programlisting>
|
||
</section>
|
||
<section>
|
||
<title>例子</title>
|
||
<para>参见<xref linkend="examples.message-counters"/>。这个例子使用消息计数器来获得一个JMS队列的相关数据。</para>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>通过JBoss应用服务器的Admin Console来管理ActiveMQ的资源</title>
|
||
<para>通过JBoss应用服务器的Admin Console可以创建与配置ActiveMQ的各种资源。</para>
|
||
<para>Admin Console允许你创建各种目标(JMS话题与队列)和JMS的连接工厂。</para>
|
||
<para>登录admin console后你在左边的树中会看到JMS Manager节点。所有ActiveMQ的资源都属于这个节点。在它的下面有JMS Queues、
|
||
Topics以及Connection Factories。分别点击它们将会看到相应的资源。下面将解释如何创建并配置它们。</para>
|
||
<section>
|
||
<title>JMS队列</title>
|
||
<para>要创建一个新的JMS队列,点击JMS Queues将列出当前的队列。在右边的窗口中有一个“add a new resource“按钮,点击这个按钮
|
||
并选择默认(JMS 队列)模板。点击“continue“。填入相应的队列名称与JNDI名称。其它的参数值都给出了合理的默认值,通常情况下
|
||
不用改动它们。在底部可以配置安全角色,如果你不提供将使用默认的配置。当这个队列成功创建后这些配置将会显示出来。除了队列的名字
|
||
和JNDI名字外,其它参数都可以在contiguration标签页下进行修改。下面就对它们分别解释。</para>
|
||
<para>点击 configuration后你将看到如下显示:</para>
|
||
<para>
|
||
<graphic fileref="images/console1.png" align="center"/>
|
||
</para>
|
||
<para>name和JNDI name是不能改变的。如果你想改变它们,必须重新创建队列。其它选项是关于地址设置与安全设置。
|
||
默认的地址设置来自于服务器的配置。如果你通过console修改或创建一个队列,那么就会增加一条新的地址设置。有关
|
||
地址设置的完整说明参见<xref linkend="queue-attributes.address-settings"/>。</para>
|
||
<para>要删除一个队列,只要点击队列名称旁边的“delete“按钮即可。与此队列相关的任何地址设置或安全设置也将被删除。</para>
|
||
<para>配置的最后一部分是安全角色。如果在创建时没有给出则默认的安全设置将会显示在屏幕上。如果它们被修改并更新则队列的安全设置
|
||
将被更新。关于安全设置参见<xref linkend="security"/>。 </para>
|
||
<para>在console中还有一个metrics标签页,它显示了队列的各项统计数据,如消息计数,接收者计数等。</para>
|
||
<para>在control标签页中可以对队列进行各种操作,比如启动和停止队列,对队列中的消息进行列表,移动,变为过期,删除等。
|
||
要进行一项操作只要点击相应的按钮,然后在出现的提示中输入相应的参数,再点击ok按钮即可。操作的結果会显示在屏幕的底部。</para>
|
||
</section>
|
||
<section>
|
||
<title>JMS话题</title>
|
||
<para>创建及配置JMS话题几乎与队列的操作是一样的。唯一不同的是这些配置应用于一个代表订阅的队列。</para>
|
||
</section>
|
||
<section>
|
||
<title>JMS连接工厂</title>
|
||
<para>JMS连接工厂的创建的操作过程与上述队列或话题的操作一致,只是配置具体的参数不同而已。关于连接工厂的参数参见配置索引。</para>
|
||
</section>
|
||
</section>
|
||
</chapter>
|