消息中间件大致分为两类:Point-to-Point(PTP) 和 Publish-Subscribe(Pub/Sub),Apusic支持这两种模型。
PTP是点对点传输消息,建立在消息队列的基础上,每个客户端对应一个消息队列,客户端发送消息到对方的消息队列中,从自己的消息队列读取消息。
Pub/Sub是将消息定位到某个层次结构栏目的节点上,Pub/Sub 通常是匿名的并能够动态发布消息,Pub/Sub 必须保证某个节点的所有发布者(Publisher)发布的信息准确无误地发送到这个节点的所有消息订阅者(Subscriber)。
JMS Parent | PTPDomain | Pub/Sub Domain |
ConnectionFactory | QueueConnectionFactory | TopicConnectionFactory |
Connection | QueueConnection | TopicConnection |
Destination | Queue | Topic |
Session | QueueSession | TopicSession |
MessageProducer | QueueSender | TopicPublisher |
MessageConsumer | QueueReceiver,QueueBrowser | TopicSubscriber |
以下是对这些接口的简单描述:
ConnectionFactory :连接工厂,JMS 用它创建连接
Connection :JMS 客户端到JMS Provider 的连接
Destination :消息的目的地
Session: 一个发送或接收消息的线程
MessageProducer: 由Session 对象创建的用来发送消息的对象
MessageConsumer: 由Session 对象创建的用来接收消息的对象
JavaBeans: JavaBeans可以用JMS Session 发送接收消息。
EJB: EJB2.0 规范中定义了新的Message-Driven Beans 组件模型。
JTA(Java Transaction API): JMS 客户端可以用JTA 启动事务。JMS Provider 可以选择是否支持分布式事务。
JTS(Java Transaction Service): JMS 可以和JTS 一起组成一个分布式事务,如将发送接收消息和更新数据库包含在一个事务里。
JNDI: JMS客户端通过JNDI 调用JMS 中的对象。
消息头(Header) - 消息头包含消息的识别信息和路由信息,消息头包含一些标准的属性如:JMSDestination,JMSMessageID 等。
消息头 | 由谁设置 |
JMSDestination | send 或 publish 方法 |
JMSDeliveryMode | send 或 publish 方法 |
JMSExpiration | send 或 publish 方法 |
JMSPriority | send 或 publish 方法 |
JMSMessageID | send 或 publish 方法 |
JMSTimestamp | send 或 publish 方法 |
JMSCorrelationID | 客户 |
JMSReplyTo | 客户 |
JMSType | 客户 |
JMSRedelivered | JMS Provider |
1. 应用需要用到的属性;
2. 消息头中原有的一些可选属性;
3. JMS Provider 需要用到的属性。
标准的JMS 消息头包含以下属性:
JMSDestination --消息发送的目的地
JMSDeliveryMode --传递模式, 有两种模式: PERSISTENT 和NON_PERSISTENT,PERSISTENT 表示该消息一定要被送到目的地,否则会导致应用错误。NON_PERSISTENT 表示偶然丢失该消息是被允许的,这两种模式使开发者可以在消息传递的可靠性和吞吐量之间找到平衡点。
JMSMessageID 唯一识别每个消息的标识,由JMS Provider 产生。
JMSTimestamp 一个消息被提交给JMS Provider 到消息被发出的时间。
JMSCorrelationID 用来连接到另外一个消息,典型的应用是在回复消息中连接到原消息。
JMSReplyTo 提供本消息回复消息的目的地址。
JMSRedelivered 如果一个客户端收到一个设置了JMSRedelivered 属性的消息,则表示可能该客户端曾经在早些时候收到过该消息,但并没有签收(acknowledged)。
JMSType 消息类型的识别符。
JMSExpiration 消息过期时间,等于QueueSender 的send 方法中的timeToLive 值或TopicPublisher 的publish 方法中的timeToLive 值加上发送时刻的GMT 时间值。如果timeToLive值等于零,则JMSExpiration 被设为零,表示该消息永不过期。如果发送后,在消息过期时间之后消息还没有被发送到目的地,则该消息被清除。
JMSPriority 消息优先级,从0-9 十个级别,0-4 是普通消息,5-9 是加急消息。JMS 不要求JMS Provider 严格按照这十个优先级发送消息,但必须保证加急消息要先于普通消息到达。
消息体(Body) - JMS API 定义了5种消息体格式,也叫消息类型,你可以使用不同形式发送接收数据并可以兼容现有的消息格式,下面描述这5种类型:
消息类型 | 消息体 |
TextMessage | java.lang.String对象,如xml文件内容 |
MapMessage | 名/值对的集合,名是String对象,值类型可以是Java任何基本类型 |
BytesMessage | 字节流 |
StreamMessage | Java中的输入输出流 |
ObjectMessage | Java中的可序列化对象 |
Message | 没有消息体,只有消息头和属性。 |
TextMessage message = queueSession.createTextMessage();
message.setText(msg_text); // msg_text is a String
queueSender.send(message);
Message m = queueReceiver.receive();
if (m instanceof TextMessage) {
TextMessage message = (TextMessage) m;
System.out.println("Reading message: " + message.getText());
} else {
// Handle error
}
同步接收是指客户端主动去接收消息,JMS 客户端可以采用MessageConsumer 的receive方法去接收下一个消息。
消息的异步接收
异步接收是指当消息到达时,主动通知客户端。JMS 客户端可以通过注册一个实现MessageListener 接口的对象到MessageConsumer,这样,每当消息到达时,JMS Provider 会调用MessageListener中的onMessage 方法。
下面描述JMS PTP 模型中的主要概念和对象:
名称 | 描述 |
Queue | 由JMS Provider 管理,队列由队列名识别,客户端可以通过JNDI 接口用队列名得到一个队列对象。 |
TemporaryQueue | 由QueueConnection 创建,而且只能由创建它的QueueConnection 使用。 |
QueueConnectionFactory | 客户端用QueueConnectionFactory 创建QueueConnection 对象。 |
QueueConnection | 一个到JMS PTP provider 的连接,客户端可以用QueueConnection 创建QueueSession 来发送和接收消息。 |
QueueSession | 提供一些方法创建QueueReceiver 、QueueSender、QueueBrowser 和TemporaryQueue。如果在QueueSession 关闭时,有一些消息已经被收到,但还没有被签收(acknowledged),那么,当接收者下次连接到相同的队列时,这些消息还会被再次接收。 |
QueueReceiver | 客户端用QueueReceiver 接收队列中的消息,如果用户在QueueReceiver 中设定了消息选择条件,那么不符合条件的消息会留在队列中,不会被接收到。 |
QueueSender | 客户端用QueueSender 发送消息到队列。 |
QueueBrowser | 客户端可以QueueBrowser 浏览队列中的消息,但不会收走消息。 |
QueueRequestor | JMS 提供QueueRequestor 类简化消息的收发过程。QueueRequestor 的构造函数有两个参数:QueueSession 和queue,QueueRequestor 通过创建一个临时队列来完成最终的收发消息请求。 |
可靠性(Reliability) | 队列可以长久地保存消息直到接收者收到消息。接收者不需要因为担心消息会丢失而时刻和队列保持激活的连接状态,充分体现了异步传输模式的优势。 |
主题可以被认为是消息的传输中介,发布者(publisher)发布消息到主题,订阅者(subscribe)从主题订阅消息。主题使得消息订阅者和消息发布者保持互相独立,不需要接触即可保证消息的传送。
下面描述JMS Pub/Sub 模型中的主要概念和对象:
名称 | 描述 |
订阅(subscription) | 消息订阅分为非持久订阅(non-durable subscription)和持久订阅(durable subscrip-tion),非持久订阅只有当客户端处于激活状态,也就是和JMS Provider 保持连接状态才能收到发送到某个主题的消息,而当客户端处于离线状态,这个时间段发到主题的消息将会丢失,永远不会收到。持久订阅时,客户端向JMS 注册一个识别自己身份的ID,当这个客户端处于离线时,JMS Provider 会为这个ID 保存所有发送到主题的消息,当客户再次连接到JMS Provider时,会根据自己的ID 得到所有当自己处于离线时发送到主题的消息。 |
Topic | 主题由JMS Provider 管理,主题由主题名识别,客户端可以通过JNDI 接口用主题名得到一个主题对象。JMS 没有给出主题的组织和层次结构的定义,由JMS Provider 自己定义。 |
TemporaryTopic | 临时主题由TopicConnection 创建,而且只能由创建它的TopicConnection 使用。临时主题不能提供持久订阅功能。 |
TopicConnectionFactory | 客户端用TopicConnectionFactory 创建TopicConnection 对象。 |
TopicConnection | TopicConnection 是一个到JMS Pub/Sub provider 的连接,客户端可以用TopicConnection创建TopicSession 来发布和订阅消息。 |
TopicSession | TopicSession 提供一些方法创建TopicPublisher、TopicSubscriber、TemporaryTopic 。它还提供unsubscribe 方法取消消息的持久订阅。 |
TopicPublisher | 客户端用TopicPublisher 发布消息到主题。 |
TopicSubscriber | 客户端用TopicSubscriber 接收发布到主题上的消息。可以在TopicSubscriber 中设置消息过滤功能,这样,不符合要求的消息不会被接收。 |
Durable TopicSubscriber | 如果一个客户端需要持久订阅消息,可以使用Durable TopicSubscriber,TopSession 提供一个方法createDurableSubscriber创建Durable TopicSubscriber 对象。 |
恢复和重新派送(Recovery and Redelivery) | 非持久订阅状态下,不能恢复或重新派送一个未签收的消息。只有持久订阅才能恢复或重新派送一个未签收的消息。 |
TopicRequestor | JMS 提供TopicRequestor 类简化消息的收发过程。TopicRequestor 的构造函数有两个参数:TopicSession 和topic。TopicRequestor 通过创建一个临时主题来完成最终的发布和接收消息请求。 |
可靠性(Reliability) | 当所有的消息必须被接收,则用持久订阅模式。当丢失消息能够被容忍,则用非持久订阅模式。 |
- 用JNDI 得到ConnectionFactory 对象;
- 用JNDI 得到目标队列或主题对象,即Destination 对象;
- 用ConnectionFactory 创建Connection 对象;
- 用Connection 对象创建一个或多个JMS Session;
- 用Session 和Destination 创建MessageProducer 和MessageConsumer;
- 通知Connection 开始传递消息。
发送消息
第一,启动Apusic应用服务器。
第二,打开管理工具:在浏览器中输入http://localhost:6882,缺省管理员为admin,密码也是admin。
第三,配置队列连接创建器:在管理工具中点击“基本配置”-->“消息”,点击“队列连接创建器”,如果存在JNDI名为 “jms/QueueConnectionFactory”的队列连接创建器,则无须创建,否则点击“创建”,添加必要信息,“队列连接创建器名称”为 “QueueConnectionFactory”,“队列连接创建器JNDI名”为“jms/QueueConnectionFactory”,“连接 是否可以匿名访问”为“是”,其它项为缺省设置,点击“保存”。如下:
第四,配置队列:在管理工具中点击“基本配置”-->“消息”,点击“队列”,如果存在JNDI名为 “jms/QueueConnectionFactory”的队列,则无须创建,否则点击“创建”,添加必要信息,“队列名称”为 “testQueue”,“队列JNDI名”为“myQueue”,其它项为缺省设置,点击“保存”。如下:
第五,编写发送消息客户端代码:Send.java
import javax.jms.*;
import javax.naming.*;
import java.io.*;
import java.util.*;
import java.rmi.RemoteException;/**
* Title: JMS
* Description: JMS Test
* Copyright: Copyright (c) 2002
* Company: Apusic
* @author Michael
* @version 1.0
*/
public class Send{
String queueName = "myQueue";
QueueConnectionFactory queueConnectionFactory = null;
Queue queue = null;
QueueConnection queueConnection = null;
QueueSession queueSession = null;
QueueSender queueSender = null;
TextMessage message = null;
public static void main(String[] args) throws Exception {
InitialContext ic = getInitialContext();
Send sender = new Send();
sender.init(ic) ;
sender.sendMessage();
sender.close();
}
public void init(InitialContext ctx) throws Exception{
queueConnectionFactory = (QueueConnectionFactory)ctx.lookup("jms/QueueConnectionFactory");
queueConnection = queueConnectionFactory.createQueueConnection();
queue = (Queue) ctx.lookup(queueName);
}
public void sendMessage() throws JMSException,RemoteException{
queueSession = queueConnection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
queueSender = queueSession.createSender(queue);
queueSender.setDeliveryMode(DeliveryMode.PERSISTENT);
message = queueSession.createTextMessage();
message.setText("The Message from myQueue");
queueSender.send(message);
}
public void close() throws JMSException{
if(queueConnection!=null)
queueConnection.close();
}
private static InitialContext getInitialContext() throws NamingException{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.apusic.jndi.InitialContextFactory");
env.put(Context.PROVIDER_URL, "rmi://localhost:6888");
return (new InitialContext(env));
}
}
如果管理工具中没有JNDI名为“jms/QueueConnectionFactory”的队列连接创建器和“myQueue”的队列,则依照上面一到四步进行设置,否则可直接编写接收消息客户端代码:Receive.java
import javax.jms.*;
import javax.naming.*;
import java.io.*;
import java.util.*;
import java.rmi.RemoteException;/**
* Title: JMS
* Description: JMS Test
* Copyright: Copyright (c) 2002
* Company: Apusic
* @author Michael
* @version 1.0
*/
public class Receive{
String queueName = "myQueue";
QueueConnectionFactory queueConnectionFactory = null;
Queue queue = null;
QueueConnection queueConnection = null;
QueueSession queueSession = null;
QueueReceiver queueReceiver = null;
TextMessage message = null;
public static void main(String[] args) throws Exception {
InitialContext ic = getInitialContext();
Receive receiver = new Receive();
receiver.init(ic) ;
receiver.TBreceiveMessage();//你可以在此处调用YBreceiveMessage
receiver.close();
}
public void init(InitialContext ctx) throws Exception{
queueConnectionFactory = (QueueConnectionFactory)ctx.lookup("jms/QueueConnectionFactory");
queueConnection = queueConnectionFactory.createQueueConnection();
queue = (Queue) ctx.lookup(queueName);
}
public void TBreceiveMessage() throws NamingException, JMSException,RemoteException{
queueSession = queueConnection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
queueReceiver = queueSession.createReceiver(queue);
queueConnection.start();
for (;;) {
message = (TextMessage) queueReceiver.receive();
System.out.println("Reading message: " + message.getText());
if (message.getText().equals("quit"))
break;
}
}
public void YBreceiveMessage() throws NamingException, JMSException,RemoteException,IOException{
queueSession = queueConnection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
queueReceiver = queueSession.createReceiver(queue);
//register my textListener which comes from MessageListener
TextMessageListener textListener = new TextMessageListener();
queueReceiver.setMessageListener(textListener);
queueConnection.start();
System.out.println("To end program, enter Q or q, then ");
InputStreamReader reader = new InputStreamReader(System.in);
char answer = '/0';
while (!((answer == 'q') || (answer == 'Q')))
answer = (char)reader.read();
}
public void close() throws JMSException{
if(queueReceiver!=null)
queueReceiver.close();
if(queueSession!=null)
queueSession.close();
if(queueConnection!=null)
queueConnection.close();
}
private static InitialContext getInitialContext() throws NamingException{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.apusic.jndi.InitialContextFactory");
env.put(Context.PROVIDER_URL, "rmi://localhost:6888");
return (new InitialContext(env));
}
}
import javax.jms.MessageListener;
import javax.jms.Message;
import javax.jms.TextMessage;
import javax.jms.JMSException;
/**
* Title: JMS
* Description: JMS Test
* Copyright: Copyright (c) 2002
* Company: Apusic
* @author Michael
* @version 1.0
*/
public class TextMessageListener implements MessageListener {
public TextMessageListener() {}
public void onMessage(Message m) {
TextMessage msg = (TextMessage) m;
try {
System.out.println("Async reading message: " + msg.getText() +
" (priority=" + msg.getJMSPriority() + ")");
} catch (JMSException e) {
System.out.println("Exception in onMessage(): " + e.toString());
}
}
}
如果是异步接收消息,在运行Receive 的窗口中可以看到输出:
To end program, enter Q or q, then
Async reading message: The Second Message from testQueue (priority=4)
如果是同步接收消息,在运行Receive 的窗口中可以看到输出:
Reading message: The Message from testQueue
发布消息
如果管理工具中没有JNDI名为“jms/TopicConnectionFactory”的队列连接创建器和“myTopic”的队列,则依照上面一到四步进行设置,否则可直接编写发布消息客户端代码:Published.java
import javax.jms.*;
import javax.naming.*;
import java.io.*;
import java.util.*;
import java.rmi.RemoteException;/**
* Title: JMS
* Description: JMS Test
* Copyright: Copyright (c) 2002
* Company: Apusic
* @author Michael
* @version 1.0
*/
public class Published{
String topicName = "myTopic";
TopicConnectionFactory topicConnectionFactory = null;
Topic topic = null;
TopicConnection topicConnection = null;
TopicSession topicSession = null;
TopicPublisher topicPublisher = null;
String msgText = null;
TextMessage message = null;
public static void main(String[] args) throws Exception {
InitialContext ic = getInitialContext();
Published publisher = new Published();
publisher.init(ic) ;
publisher.publish();
publisher.close();
}
public void init(InitialContext ctx) throws Exception{
topicConnectionFactory = (TopicConnectionFactory)ctx.lookup("jms/TopicConnectionFactory");
topicConnection = topicConnectionFactory.createTopicConnection();
topic = (Topic) ctx.lookup(topicName);
}
public void publish() throws NamingException, JMSException,RemoteException{
topicSession = topicConnection.createTopicSession(false,Session.AUTO_ACKNOWLEDGE);
topicPublisher = topicSession.createPublisher(topic);
message = topicSession.createTextMessage();
msgText = "This is the published message";
message.setText(msgText);
topicPublisher.publish(message);
}
public void close() throws JMSException{
if(topicConnection!=null)
topicConnection.close();
}
private static InitialContext getInitialContext() throws NamingException{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.apusic.jndi.InitialContextFactory");
env.put(Context.PROVIDER_URL, "rmi://localhost:6888");
return (new InitialContext(env));
}
}
import javax.jms.*;
import javax.naming.*;
import java.io.*;
import java.util.*;
import java.rmi.RemoteException;/**
* Title: JMS
* Description: JMS Test
* Copyright: Copyright (c) 2002
* Company: Apusic
* @author Michael
* @version 1.0
*/
public class Subscriber{
String topicName = "myTopic";
TopicConnectionFactory topicConnectionFactory = null;
TopicConnection topicConnection = null;
Topic topic = null;
TopicSession topicSession = null;
TopicSubscriber topicSubscriber = null;
TextMessage message = null;
String id = "durable";
public static void main(String[] args) throws Exception {
InitialContext ic = getInitialContext();
Subscriber subscriber = new Subscriber();
subscriber.init(ic) ;
subscriber.subscribe();
subscriber.close();
}
public void init(InitialContext ctx) throws Exception{
topicConnectionFactory = (TopicConnectionFactory)ctx.lookup("jms/TopicConnectionFactory");
topicConnection = topicConnectionFactory.createTopicConnection();
topicConnection.setClientID(id) ;
topic = (Topic) ctx.lookup(topicName);
}
public void subscribe() throws NamingException, JMSException,RemoteException{
topicSession = topicConnection.createTopicSession(false,Session.AUTO_ACKNOWLEDGE);
topicSubscriber = topicSession.createDurableSubscriber(topic,id);
topicConnection.start();
message = (TextMessage) topicSubscriber.receive();
System.out.println("SUBSCRIBER THREAD: Reading message: " + message.getText());
}
public void close() throws JMSException{
if(topicConnection!=null)
topicConnection.close();
}
private static InitialContext getInitialContext() throws NamingException{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.apusic.jndi.InitialContextFactory");
env.put(Context.PROVIDER_URL, "rmi://localhost:6888");
return (new InitialContext(env));
}
}
SUBSCRIBER THREAD: Reading message: This is the published message
对于队列,可以设定发送(send)、接收(receive)和浏览(browse)权限;对于主题,可以设定发布(publish)、订阅(subscribe)、持久订阅(subscribe-durable)和取消持久订阅(unsubscribe)权限。
客户端用QueueConnectionFactory 的createQueueConnection(java.lang.String userName,java.lang.String password)方法创建队列连接时输入用户身份,或者用createTopicConnection(java.lang.String userName, java.lang.String password)方法创建主题连接时输入用户身份。
下面的例子授权用户larry 可以对队列testQueue 进行接收和浏览:
首先创建testQueue队列,如果Apusic不存在testQueue队列,则通过管理工具创建,方法同上。
建立安全角色(security-role)rbt,将该角色映射到用户larry,使larry 拥有该角色包含的所有权限。如果Apuisc应用服务器不存在larry用户,在管理工具中“用户管理”-->“用户/组” 中创建larry用户。然后可参考apusic.jar中jms.dtd的定义在jms.xml中加入如下片段:
<security-role>
<role-name>rbt</role-name>
<principal>larry</principal>
</security-role>
设置安全角色rbt的权限
<destination-permission>
<role-name>rbt</role-name>
<destination-method>
<queue-name>testQueue</queue-name>
<method-name>receive</method-name>
<method-name>browse</method-name>
</destination-method>
</destination-permission>
Client----->Computer A(Router x)----------Computer B(Router z)
| Connector 3 |
| Connector 1 |Connector 2
| |
Computer C(Router y)--------------------
...
<SERVICE
CLASS="com.apusic.jms.server.JMSServer">
<ATTRIBUTE NAME="BackStoreDirectory" VALUE="store/jms"/>
</SERVICE>
...
- 路由器的配置 其它路由器的配置依次类推。
- 路由连接器的配置
每个JMS网络中的消息路由器都是通过路由连接器进行连接的,每个路由器可以拥有多个路由连接器连接到其它节点。对路由连接器的配置是通过在 apusic.conf配置文件中增加路由连接器服务实现的。以消息路由图示-2中的A节点为例,需要申明到节点B的路由连接器,则可在apusic.conf文件中加入如下配置段:
...
<SERVICE
CLASS="com.apusic.jms.routing.RoutingConnector" NAME="Connector:Name=toB">
<ATTRIBUTE NAME="RemoteHost" VALUE="computerB"/>
<ATTRIBUTE NAME="RemotePort" VALUE="6888"/>
</SERVICE>
...其中computerB是B的主机名,toB是此路由连接器区别于其他路由连接器的自由定义名字,6888是默认的JMS服务端口,具体使用中,可将其更改为实际的路由连接器名、主机名与端口。消息路由图示-2中其它节点上的路由连接器配置如此类推。
属性 | 描述 | 值类型 | 缺省值 |
type | 连接创建器的消息模型(PTP和Pub/Sub)类型 | “QueueConnectionFactory”或“TopicConnectionFactory”,分别对应PTP和Pub/Sub模型,此属性必须定义 | 无 |
pooled | 指定此连接创建器是否对其管理的连接使用连接池 | “True”或“False” | “False” |
secure | 指定连接创建器所提供连接的通讯方式 | “True”或“False” | “False” |
anonymous | 是否授权匿名用户访问此连接创建器 | “True”或“False” | “True” |
client-id | 由于标识连接客户状态的标识符,通常被用于Pub/Sub模型中的持久订阅(Durable subscription) | 字符串,此属性是可选的 | 无 |
default-delivery-mode | 使用由此连接创建器生成的连接发送消息时,缺省的发送方式 | “persistent”或“non-persistent” | “non-persistent” |
default-priority | 使用由此连接创建器生成的连接发送消息时,缺省的优先级 | 数字(0~9) | “4” |
default-time-to-live | 使用由此连接创建器生成的连接发送消息时,对于已发送的消息,消息系统保留此消息的缺省时间长度,单位为毫秒。 | 整型 | 0 |
min-pool-size | 此连接创建器对应的连接池中,所保持的最少连接数 | 整型 | 5 |
min-pool-size | 此连接创建器对应的连接池中,所保持的最少连接数 | 整型 | 30 |
idle-timeout | 连接等待超时时间。当连接池中的某个连接等待被使用的实际时间超过此属性数值时,连接池自动关闭此连接 | 整型,单位是秒 | 300 |
属性 | 描述 | 值类型 | 缺省值 |
cache-size | 队列缓冲中保留的消息个数 | 整型 | 20 |
expiry-check-interval | 系统检测消息队列中消息是否过期的时间间隔,单位是秒 | 整型 | 60 |
- description,可选标记,对此访问许可的描述 ;
- role-name,必须使用至少一个这种标记申明的元素,可以是多个,用于表示此访问许可所包含的在security-role中申明的安全角色;
- destination-method,必须使用至少一个这种标记申明的元素,可以是多个,用于表示此访问许可所包含的客户对消息接收站(Destination)能进行的操作。
- description,可选标记,对此destination-method的描述 ;
- queue-name或topic-name,必须有至少一个这两种标记申明的元素,而且它的值必须是对应的jms.xml中已申明的queue或topic元素,用于说明此访问许可包含的消息接收站(Destination);
- method-name,必须使用至少一个这种标记申明的元素,可 以是多个,通过方法名,指定对指定队列(queue)或主题(topic)所能进行的客户操作。对于指定的队列(queue),每个method- name元素的值可以是send、receive或browse中之一;对于指定的主题(topic),每个method-name元素的值可以是 publish、subscribe、subscribe-durable或unsubscribe中之一;