JMS 的基本構件
- 連接工廠
- 連接工廠是客戶用來創建連接的對象,例如ActiveMQ 提供的ActiveMQConnectionFactory。
- 連接
- JMS Connection 封裝了客戶與JMS 提供者之間的一個虛擬的連接。
- 會話
- JMS Session是生產和消費消息的一個單線程上下文。
- 會話用於創建消息生產者(producer)、消息消費者(consumer)和消息 (message)等。
- 會話提供了一個事務性的上下文,在這個上下文中,一組發送和接收被組合到了一個原子操作中。
- 目的地
- 目的地是客戶用來指定它生產的消息的目標和它消費的消息的來源的對象。
JMS1.0.2 規範中定義了兩種消息傳遞域:點對點 (PTP)消息傳遞域和發佈/訂閱消息傳遞域。
- 點對點消息傳遞域的特點如下:
- 每個消息只能有一個消費者。
- 消息的生產者和消費者之間沒有時間上的相關性。無論消費者在生產者發送消息的時候是否處於運行狀態,它都可以提取消息。
- 發佈/訂閱消息傳遞域的特點如下:
- 每個消息可以有多個消費者。
- 生產者和消費者之間有時間上的相關性。
- 訂閱一個主題的消費者只能消費自它訂閱之後發佈的消息。
- JMS規範允許客戶創建持久訂閱,這在一定程度上放鬆了時間上的相關性要求。
- 持久訂閱允許消費者消費它在未處於激活狀態時發送的消息。
- 在點對點消息傳遞域中,目的地被成爲隊列(queue);在發佈/訂閱消息傳遞域中,目的地被成爲主題(topic)。
消息生產者
- 消息生產者是由會話創建的一個對象,用於把消息發送到一個目的地。
消息消費者
- 消息消費者是由會話創建的一個對象,它用於接收發送到目的地的消息。
- 消息的消費可以採用以下兩種方法之一:
- 同步消費。通過調用 消費者的receive方法從目的地中顯式提取消息。
- receive方法可以一直阻塞到消息到達。
- 異步消費。客戶可以爲消費者註冊一個消息監聽器,以定義在消息到達時所採取的動作。
- 同步消費。通過調用 消費者的receive方法從目的地中顯式提取消息。
消息
- JMS消息由以下三部分組成:
- 消息頭。每個消息頭字段都有相應的getter和setter方法。
- 消息屬性。如果需要除消息頭字段以外的值,那麼可以使用消息屬性。
- 消息體。JMS定義的消息類型有TextMessage、MapMessage、BytesMessage、StreamMessage和 ObjectMessage。
JMS 的可靠性機制
- 確認
- 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。
- Session.AUTO_ACKNOWLEDGE。
- 持久性
- JMS 支持以下兩種消息提交模式:
- PERSISTENT。指示JMS provider持久保存消息,以保證消息不會因爲JMS provider的失敗而丟失。
- NON_PERSISTENT。不要求JMS provider持久保存消息。
- JMS 支持以下兩種消息提交模式:
- 優先級
- 可以使用消息優先級來指示JMS provider首先提交緊急的消息。
- 優先級分10 個級別,從0(最低)到9(最高)。
- 如果不指定優先級,默認級別是4。
- 需要注意的是,JMS provider並不一定保證按照優先級的順序提交消息。
- 消息過期
- 可以設置消息在一定時間後過期,默認是永不過期。
- 臨時目的地
- 可以通過會話上的createTemporaryQueue方法和createTemporaryTopic方法來創建臨時目的地。
- 它們的存在時間只限於創建它們的連接所保持的時間。
- 只有創建該臨時目的地的連接上的消息消費者才能夠從臨時目的地中提取消息。
- 持久訂閱
- 首先消息生產者必須使用PERSISTENT提交消息。
- 客戶可以通過會話上的 createDurableSubscriber方法來創建一個持久訂閱,
- 該方法的第一個參數必須是一個topic。
- 第二個參數是訂閱的名稱。
-
JMS provider會存儲發佈到持久訂閱對應的topic上的消息。
-
如果最初創建持久訂閱的客戶或者任何其它客戶使用相同的連接工廠和連接的客戶ID、相同的主題和相同的訂閱名再次調用會話上的createDurableSubscriber方法,那麼該持久訂閱就會被激活。
-
JMS provider會向客戶發送客戶處於非激活狀態時所發佈的消息。
-
持久訂閱在某個時刻只能有一個激活的訂閱者。
-
持久訂閱在創建之後會一直保留,直到應用程序調用會話上的unsubscribe方法。
-
本地事務
-
在一個JMS客戶端,可以使用本地事務來組合消息的發送和接收。
-
JMS Session 接口提供了commit和rollback方法。
-
事務提交意味着生產的所有消息被髮送,消費的所有消息被確認;
-
事務回滾意味着生產的所有消 息被銷燬,消費的所有消息被恢復並重新提交,除非它們已經過期。
-
-
事務性的會話總是牽涉到事務處理中,commit或rollback方法一旦被調用,一個事務就結束了,而另一個事務被開始。
-
關閉事務性會話將回滾其中的事務。
-
-
需要注意的是,
-
如果使用請求/回覆機制,即發送一個消息,同時希望在同一個事務中等待接收該消息的回覆,那麼程序將被掛起,因爲直到事務提交,發送操作纔會真正執行。
-
需要注意的還有一個,消息的生產和消費不能包含在同一個事務中。
-
-
以下是不同消息傳遞域的相應接口:
JMS 公共 |
點對點域 |
發佈/訂閱域 |
ConnectionFactory |
QueueConnectionFactory |
TopicConnectionFactory |
Connection |
QueueConnection |
TopicConnection |
Destination |
Queue |
Topic |
Session |
QueueSession |
TopicSession |
MessageProducer |
QueueSender |
TopicPublisher |
MessageConsumer |
QueueReceiver |
TopicSubscriber |