1.JMS概述
JAVA 消息服務(wù)(JMS)定義了Java 中訪問消息中間件的接口。JMS只是接口,并沒有給予實現(xiàn),實現(xiàn)JMS接口的消息中間件稱為JMS Provider
消息中間件提供企業(yè)數(shù)據(jù)的異步傳輸,通過消息中間件,一些原本互相孤立的業(yè)務(wù)組件可以組合成一個可靠的、靈活的系統(tǒng)。也可以模擬實現(xiàn)同步傳輸,但其實質(zhì)仍然是異步的。
JMS 支持兩種消息類型PTP (Point-to-Point)和Pub/Sub(Publish-Subscribe),分別稱作:PTP Domain 和Pub/Sub Domain。
PTP的主要特點是:
1)一條消息只有一個使用者
2)不存在時間限制
Pub/Sub主要特點有:
1)一條消息可以有多個使用者
2)存在時間限制。訂閱者可以使用持久方式來訂閱消息,但是也會過期或者取消訂閱
這兩種接口都繼承統(tǒng)一的JMS Parent 接口,JMS 主要接口如下所示:
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 用它創(chuàng)建連接
Connection :JMS 客戶端到JMS Provider 的連接
Destination :消息的目的地
Session: 一個發(fā)送或接收消息的線程
MessageProducer: 由Session 對象創(chuàng)建的用來發(fā)送消息的對象
MessageConsumer: 由Session 對象創(chuàng)建的用來接收消息的對象
2.JMS消息模型
JMS 消息由以下幾部分組成:消息頭,屬性,消息體。
消息頭(Header) -消息頭包含消息的識別信息和路由信息,消息頭包含一些標(biāo)準(zhǔn)的屬性如:JMSDestination,JMSMessageID等。
消息頭 |
由誰設(shè)置 |
JMSDestination |
send 或 publish 方法 |
JMSDeliveryMode |
send 或 publish 方法 |
JMSExpiration |
send 或 publish 方法 |
JMSPriority |
send 或 publish 方法 |
JMSMessageID |
send 或 publish 方法 |
JMSTimestamp |
send 或 publish 方法 |
JMSCorrelationID |
客戶 |
JMSReplyTo |
客戶 |
JMSType |
客戶 |
JMSRedelivered |
JMS Provider |
屬性(Properties) -除了消息頭中定義好的標(biāo)準(zhǔn)屬性外,JMS提供一種機制增加新屬性到消息頭中,這種新屬性包含以下幾種:
-
應(yīng)用需要用到的屬性;
-
消息頭中原有的一些可選屬性;
-
JMS Provider 需要用到的屬性。
標(biāo)準(zhǔn)的JMS 消息頭包含以下屬性:
JMSDestination --消息發(fā)送的目的地。
JMSDeliveryMode --傳遞模式,有兩種模式:PERSISTENT和NON_PERSISTENT,PERSISTENT表示該消息一定要被送到目的地,否則會導(dǎo)致應(yīng)用錯誤。 NON_PERSISTENT表示偶然丟失該消息是被允許的,這兩種模式使開發(fā)者可以在消息傳遞的可靠性和吞吐量之間找到平衡點。
JMSMessageID 唯一識別每個消息的標(biāo)識,由JMS Provider 產(chǎn)生。
JMSTimestamp 一個消息被提交給JMS Provider 到消息被發(fā)出的時間。
JMSCorrelationID 用來連接到另外一個消息,典型的應(yīng)用是在回復(fù)消息中連接到原消息。
JMSReplyTo 提供本消息回復(fù)消息的目的地址。
JMSRedelivered如果一個客戶端收到一個設(shè)置了JMSRedelivered屬性的消息,則表示可能該客戶端曾經(jīng)在早些時候收到過該消息,但并沒有簽收(acknowledged)。
JMSType 消息類型的識別符。
JMSExpiration 消息過期時間,等于QueueSender 的send方法中的timeToLive值或TopicPublisher 的publish 方法中的timeToLive值加上發(fā)送時刻的GMT時間值。如果timeToLive值等于零,則JMSExpiration被設(shè)為零,表示該消息永不過期。如果發(fā)送后,在消息過期時間之后消息還沒有被發(fā)送到目的地,則該消息被清除。
JMSPriority 消息優(yōu)先級,從0-9 十個級別,0-4 是普通消息,5-9 是加急消息。JMS 不要求JMS Provider嚴(yán)格按照這十個優(yōu)先級發(fā)送消息,但必須保證加急消息要先于普通消息到達(dá)。
消息體(Body) - JMS API定義了5種消息體格式,也叫消息類型,你可以使用不同形式發(fā)送接收數(shù)據(jù)并可以兼容現(xiàn)有的消息格式,下面描述這5種類型:
消息類型 |
消息體 |
TextMessage |
java.lang.String對象,如xml文件內(nèi)容 |
MapMessage |
名/值對的集合,名是String對象,值類型可以是Java任何基本類型 |
BytesMessage |
字節(jié)流 |
StreamMessage |
Java中的輸入輸出流 |
ObjectMessage |
Java中的可序列化對象 |
Message |
沒有消息體,只有消息頭和屬性 |
Message是以上5類的基礎(chǔ)。最常用的是ObjectMessage和TextMessage
3.消息的同步異步接收
消息的同步接收
同步接收是指客戶端主動去接收消息,JMS 客戶端可以采用MessageConsumer的receive方法去接收下一個消息。
消息的異步接收
異步接收是指當(dāng)消息到達(dá)時,主動通知客戶端。JMS客戶端可以通過注冊一個實現(xiàn)MessageListener接口的對象到MessageConsumer,這樣,每當(dāng)消息到達(dá)時,JMS Provider 會調(diào)用MessageListener中的onMessage 方法。
4.PTP模型
PTP(Point-to-Point)模型是基于隊列的,發(fā)送方發(fā)消息到隊列,接收方從隊列接收消息,隊列的存在使得消息的異步傳輸成為可能。和郵件系統(tǒng)中的郵箱一樣,隊列可以包含各種消息,JMS Provider 提供工具管理隊列的創(chuàng)建、刪除。JMS PTP模型定義了客戶端如何向隊列發(fā)送消息,從隊列接收消息,瀏覽隊列中的消息。
下面描述JMS PTP 模型中的主要概念和對象:
名稱 |
描述 |
Queue |
由JMS Provider 管理,隊列由隊列名識別,客戶端可以通過JNDI接口用隊列名得到一個隊列對象。 |
TemporaryQueue |
由QueueConnection 創(chuàng)建,而且只能由創(chuàng)建它的QueueConnection 使用。 |
QueueConnectionFactory |
客戶端用QueueConnectionFactory 創(chuàng)建QueueConnection 對象。 |
QueueConnection |
一個到JMS PTP provider 的連接,客戶端可以用QueueConnection創(chuàng)建QueueSession來發(fā)送和接收消息。 |
QueueSession |
提 供一些方法創(chuàng)建QueueReceiver、QueueSender、QueueBrowser和TemporaryQueue。如果在 QueueSession關(guān)閉時,有一些消息已經(jīng)被收到,但還沒有被簽收(acknowledged),那么,當(dāng)接收者下次連接到相同的隊列時,這些消息 還會被再次接收。 |
QueueReceiver |
客戶端用QueueReceiver接收隊列中的消息,如果用戶在QueueReceiver中設(shè)定了消息選擇條件,那么不符合條件的消息會留在隊列中,不會被接收到。 |
QueueSender |
客戶端用QueueSender 發(fā)送消息到隊列。 |
QueueBrowser |
客戶端可以QueueBrowser 瀏覽隊列中的消息,但不會收走消息。 |
QueueRequestor |
JMS 提供QueueRequestor類簡化消息的收發(fā)過程。QueueRequestor的構(gòu)造函數(shù)有兩個參數(shù):QueueSession和queue,QueueRequestor 通過創(chuàng)建一個臨時隊列來完成最終的收發(fā)消息請求。 |
可靠性(Reliability) |
隊列可以長久地保存消息直到接收者收到消息。接收者不需要因為擔(dān)心消息會丟失而時刻和隊列保持激活的連接狀態(tài),充分體現(xiàn)了異步傳輸模式的優(yōu)勢。 |
4.Pub/Sub模型
JMS Pub/Sub 模型定義了如何向一個內(nèi)容節(jié)點發(fā)布和訂閱消息,這些節(jié)點被稱作主題(topic)。
主題可以被認(rèn)為是消息的傳輸中介,發(fā)布者(publisher)發(fā)布消息到主題,訂閱者(subscribe)從主題訂閱消息。主題使得消息訂閱者和消息發(fā)布者保持互相獨立,不需要接觸即可保證消息的傳送。
下面描述JMS Pub/Sub 模型中的主要概念和對象:
名稱 |
描述 |
訂閱(subscription) |
消息訂閱分為非持久訂閱(non-durable subscription)和持久訂閱(durablesubscrip-tion),非持久訂閱只有當(dāng)客戶端處于激活狀態(tài),也就是和JMS Provider保持連接狀態(tài)才能收到發(fā)送到某個主題的消息,而當(dāng)客戶端處于離線狀態(tài),這個時間段發(fā)到主題的消息將會丟失,永遠(yuǎn)不會收到。持久訂閱時,客戶端向JMS注冊一個識別自己身份的ID,當(dāng)這個客戶端處于離線時,JMS Provider 會為這個ID 保存所有發(fā)送到主題的消息,當(dāng)客戶再次連接到JMS Provider時,會根據(jù)自己的ID得到所有當(dāng)自己處于離線時發(fā)送到主題的消息。 |
Topic |
主題由JMS Provider 管理,主題由主題名識別,客戶端可以通過JNDI接口用主題名得到一個主題對象。JMS沒有給出主題的組織和層次結(jié)構(gòu)的定義,由JMS Provider 自己定義。 |
TemporaryTopic |
臨時主題由TopicConnection創(chuàng)建,而且只能由創(chuàng)建它的TopicConnection使用。臨時主題不能提供持久訂閱功能。 |
TopicConnectionFactory |
客戶端用TopicConnectionFactory 創(chuàng)建TopicConnection 對象。 |
TopicConnection |
TopicConnection 是一個到JMS Pub/Sub provider的連接,客戶端可以用TopicConnection創(chuàng)建TopicSession來發(fā)布和訂閱消息。 |
TopicSession |
TopicSession提供一些方法創(chuàng)建TopicPublisher、TopicSubscriber、TemporaryTopic。它還提供unsubscribe方法取消消息的持久訂閱。 |
TopicPublisher |
客戶端用TopicPublisher 發(fā)布消息到主題。 |
TopicSubscriber |
客戶端用TopicSubscriber接收發(fā)布到主題上的消息??梢栽赥opicSubscriber中設(shè)置消息過濾功能,這樣,不符合要求的消息不會被接收。 |
Durable TopicSubscriber |
如果一個客戶端需要持久訂閱消息,可以使用Durable TopicSubscriber,TopSession提供一個方法createDurableSubscriber創(chuàng)建Durable TopicSubscriber 對象。 |
恢復(fù)和重新派送(Recovery and Redelivery) |
非持久訂閱狀態(tài)下,不能恢復(fù)或重新派送一個未簽收的消息。只有持久訂閱才能恢復(fù)或重新派送一個未簽收的消息。 |
TopicRequestor |
JMS 提供TopicRequestor類簡化消息的收發(fā)過程。TopicRequestor的構(gòu)造函數(shù)有兩個參數(shù):TopicSession和topic。TopicRequestor 通過創(chuàng)建一個臨時主題來完成最終的發(fā)布和接收消息請求。 |
可靠性(Reliability) |
當(dāng)所有的消息必須被接收,則用持久訂閱模式。當(dāng)丟失消息能夠被容忍,則用非持久訂閱模 |