消息中間件大致分爲兩類: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>
...
...
<SERVICE
CLASS="com.apusic.jms.routing.RoutingConnector" NAME="Connector:Name=toB">
<ATTRIBUTE NAME="RemoteHost" VALUE="computerB"/>
<ATTRIBUTE NAME="RemotePort" VALUE="6888"/>
</SERVICE>
...
屬性 | 描述 | 值類型 | 缺省值 |
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 |
屬性 | 描述 | 值類型 | 缺省值 |
cache-size | 主題緩衝中保留的消息個數 | 整型 | 20 |
expiry-check-interval | 系統檢測消息主題中消息是否過期的時間間隔,單位是秒 | 整型 | 60 |