ActiveMQ-inAction-JMS-學習筆記
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 |