JMS Development Guide

1.JMS消息的異步與同步接收

消息的異步接收:

      異步接收是指當消息到達時,主動通知客戶端,即當消息到達時轉發到客戶端。JMS客戶端可以通過註冊一個實現MessageListener接口的對象到MessageConsumer,這樣,每當消息到達時,JMS Provider 會調用MessageListener中的onMessage 方法。所以需要創建一個消息監聽器,然後註冊一個或多個使用MessageConsumer的JMS MessageListener接口。會話(主題或隊列)負責產生某些消息,這些消息被傳送到使用onMessage方法的監聽者那裏;

客戶可以爲消費者註冊一個消息監聽器,以定義在消息到達時所採取的動作

 

消息的同步接收

      jms同步接受消息的功能(客戶端必須請求每個消息),通過調用消費者的receive方法從目的地中顯式提取消息,receive方法可以一直阻塞到消息到達,同步接收是指客戶端主動去接收消息,JMS 客戶端可以採用MessageConsumer的receive方法去接收下一個消息。

 

 

2. JMS消息域

點對點(PTP)

發佈和訂閱(Pub/Sub)

 

消息中間件大致分爲兩類:Point-to-Point(PTP)和Publish-Subscribe(Pub/Sub)

      PTP是點對點傳輸消息,建立在消息隊列的基礎上,每個客戶端對應一個消息隊列,客戶端發送消息到對方的消息隊列中,從自己的消息隊列讀取消息。

      Queue 由JMS Provider 管理,隊列由隊列名識別,客戶端可以通過JNDI接口用隊列名得到一個隊列對象。

 

      Pub/Sub是將消息定位到某個層次結構欄目的節點上,Pub/Sub通常是匿名的並能夠動態發佈消息,Pub/Sub必須保證某個節點的所有發佈者(Publisher)發佈的信息準確無誤地發送到這個節點的所有消息訂閱者(Subscriber)。

     

      消息訂閱分爲非持久訂閱(non-durable subscription)和持久訂閱(durablesubscrip-tion),非持久訂閱只有當客戶端處於激活狀態,也就是和JMS Provider保持連接狀態才能收到發送到某個主題的消息,而當客戶端處於離線狀態,這個時間段發到主題的消息將會丟失,永遠不會收到。持久訂閱時,客戶端向JMS註冊一個識別自己身份的ID,當這個客戶端處於離線時,JMS Provider 會爲這個ID 保存所有發送到主題的消息,當客戶再次連接到JMS Provider時,會根據自己的ID得到所有當自己處於離線時發送到主題的消息。

 

      Topic 主題由JMS Provider 管理,主題由主題名識別,客戶端可以通過JNDI接口用主題名得到一個主題對象。

 

 

3. JMS常用接口說明

      ConnectionFactory :連接工廠,JMS 用它創建連接

      Connection :JMS 客戶端到JMS Provider 的連接

      Destination :消息的目的地

      Session: 一個發送或接收消息的線程

      MessageProducer: 由Session 對象創建的用來發送消息的對象

      MessageConsumer: 由Session 對象創建的用來接收消息的對象

 

 

4.JMS的可靠性機制

(1) 確認

       JMS消息只有在被確認之後,才認爲已經被成功地消費了。消息的成功消費通常包含三個階段:客戶接收消息、客戶處理消息和消息被確認。

      在事務性會話中,當一個事務被提交的時候,確認自動發生。在非事務性會話中,消息何時被確認取決於創建會話時的應答模式(acknowledgement mode)。該參數有以下三個可選值:

      Session.AUTO_ACKNOWLEDGE。當客戶成功的從receive方法返回的時候,或者從MessageListener.onMessage方法成功返回的時候,會話自動確認客戶收到的消息。

      Session.CLIENT_ACKNOWLEDGE。客戶通過消息的acknowledge方法確認消息。需要注意的是,在這種模式中,確認是在會話 層上進行:確認一個被消費的消息將自動確認所有已被會話消費的消息。例如,如果一個消息消費者消費了10個消息,然後確認第5個消息,那麼所有10個消息 都被確認。

      Session.DUPS_ACKNOWLEDGE。該選擇只是會話遲鈍第確認消息的提交。如果JMS provider失敗,那麼可能會導致一些重複的消息。如果是重複的消息,那麼JMS provider必須把消息頭的JMSRedelivered字段設置爲true。

 

(2)持久性

  JMS 支持以下兩種消息提交模式:

      PERSISTENT。指示JMS provider持久保存消息,以保證消息不會因爲JMS provider的失敗而丟失。

      NON_PERSISTENT。不要求JMS provider持久保存消息。

 

(3)優先級

      可以使用消息優先級來指示JMS provider首先提交緊急的消息。優先級分10個級別,從0(最低)到9(最高)。如果不指定優先級,默認級別是4。需要注意的是,JMS provider並不一定保證按照優先級的順序提交消息。

 

(4)消息過期

      可以設置消息在一定時間後過期,默認是永不過期。

 

(5)臨時目的地

      可以通過會話上的createTemporaryQueue方法和createTemporaryTopic方法來創建臨時目的地。它們的存在時間只限於創建它們的連接所保持的時間。只有創建該臨時目的地的連接上的消息消費者才能夠從臨時目的地中提取消息。

 

(6)持久訂閱

      首先消息生產者必須使用PERSISTENT提交消息。客戶可以通過會話上的createDurableSubscriber方法來創建一個持久訂閱,該方法的第一個參數必須是一個topic。第二個參數是訂閱的名稱。

      JMS provider會存儲發佈到持久訂閱對應的topic上的消息。如果最初創建持久訂閱的客戶或者任何其它客戶使用相同的連接工廠和連接的客戶ID、相同 的主題和相同的訂閱名再次調用會話上的createDurableSubscriber方法,那麼該持久訂閱就會被激活。JMS provider會象客戶發送客戶處於非激活狀態時所發佈的消息。

      持久訂閱在某個時刻只能有一個激活的訂閱者。持久訂閱在創建之後會一直保留,直到應用程序調用會話上的unsubscribe方法。

 

(7)本地事務

      在一個JMS客戶端,可以使用本地事務來組合消息的發送和接收。JMS Session接口提供了commit和rollback方法。事務提交意味着生產的所有消息被髮送,消費的所有消息被確認;事務回滾意味着生產的所有消息被銷燬,消費的所有消息被恢復並重新提交,除非它們已經過期。

      事務性的會話總是牽涉到事務處理中,commit或rollback方法一旦被調用,一個事務就結束了,而另一個事務被開始。關閉事務性會話將回滾其中的事務。

      需要注意的是,如果使用請求/回覆機制,即發送一個消息,同時希望在同一個事務中等待接收該消息的回覆,那麼程序將被掛起,因爲知道事務提交,發送操作纔會真正執行。

      需要注意的還有一個,消息的生產和消費不能包含在同一個事務中。

 

5. JMS消息類型:

TextMessage、MapMessage、BytesMessage、StreamMessage和ObjectMessage

ActiveMQ端口:1099(JMX),61616(默認的TransportConnector)

 

6.JMS 消息組成

JMS 消息由以下幾部分組成:消息頭,屬性,消息體。

消息頭:

      包含客戶端及 JSM 提供程序所需的標識、路由消息的信息

      各種類型的消息都具有相同的消息頭結構

消息頭包含以下屬性:

      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嚴格按照這十個優先級發送消息,但必須保證加急消息要先於普通消息到達。

 

屬性(Properties) -除了消息頭中定義好的標準屬性外,JMS提供一種機制增加新屬性到消息頭中,這種新屬性包含以下幾種:

屬性的值可以是int,boolean,byte,short,long,float,double,String等;

可以通過getPropertyNames來取得所有的屬性名;通過clearProperties來刪除消息的屬性;

Jms定義的屬性主要是一些發送消息的用戶(應用)標識,轉發消息的重試次數等,如:JMSXDeliveryCount.....

 

應用需要用到的屬性;

消息頭中原有的一些可選屬性;

JMS Provider 需要用到的屬性。

消息體(Body) - JMS API定義了5種消息體格式

TextMessage、MapMessage(key是String,value是java原始類型)、BytesMessage、StreamMessage和ObjectMessage

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章