JMS簡介
該文主要介紹了JMS的一些基本概念、常用的編程模型及消息結構,并分別介紹了PTP和Pub/Sub兩種模型中常見的類。
ActiveMQ與JMS的區別與聯系
Java消息服務(JMS)定義了Java中訪問消息中間件的接口。JMS只是接口,并沒有給予實現,實現JMS接口的消息中間件稱為JMS Provider,如ActiveMQ。準確的來說JMS只是SUN為消息中間件提供的一套規范接口,具體的實現由各個廠家根據該規范去實現。ActiveMQ就是其中的一個實現。
JMS中涉及到的術語
JMS Provider:實現JMS接口的消息中間件;
PTP:Point To Point,即點對點的消息模型;
Pub/Sub:Publish/Subscribe,即發布/訂閱的消息模型;
Queue:隊列目標;
Topic:主題目標;
ConnectionFactory:連接工廠,JMS用它創建連接;
Connection:JMS客戶端到JMS Provider的連接;
Destination:消息的目的地;
Session:會話,一個發送或接收消息的線程;
MessageProducer:由Session對象創建的用來發送消息的對象;
MessageConsumer:由Session對象創建的用來接收消息的對象;
Acknowledge:簽收;
Transaction:事務。
JMS的編程模型
在 JMS 編程模型中,JMS 客戶端(組件或應用程序)通過 JMS 消息服務交換消息。消息生產者將消息發送至消息服務,消息消費者則從消息服務接收這些消息。這些消息傳送操作是使用一組實現 JMS 應用編程接口 (API) 的對象(由 JMS Provide提供)來執行的。
在 JMS 編程模型中,JMS 客戶端使用 ConnectionFactory 對象創建一個連接,向消息服務發送消息以及從消息服務接收消息均是通過此連接來進行。Connection 是客戶端與消息服務的活動連接。創建連接時,將分配通信資源以及驗證客戶端。這是一個相當重要的對象,大多數客戶端均使用一個連接來進行所有的消息傳送。
連接用于創建會話。Session 是一個用于生成和使用消息的單線程上下文。它用于創建發送的生產者和接收消息的消費者,并為所發送的消息定義發送順序。會話通過大量確認選項或通過事務來支持可靠傳送。
客戶端使用 MessageProducer 向指定的物理目標(在 API 中表示為目標身份對象)發送消息。生產者可指定一個默認傳送模式(持久性消息與非持久性消息)、優先級和有效期值以控制生產者向物理目標發送的所有消息。
同樣,客戶端使用 MessageConsumer 對象從指定的物理目標(在 API 中表示為目標對象)接收消息。消費者可使用消息選擇器,借助它,消息服務可以只向消費者發送與選擇標準匹配的那些消息。
消費者可以支持同步或異步消息接收。異步使用可通過向消費者注冊 MessageList ener 來實現。當會話線程調用 MessageListener 對象的 onMessage 方法時,客戶端將使用消息。
JMS的消息結構
消息頭包含消息的識別信息和路由信息,消息頭包含一些標準的屬性如: JMSDesti
nation,JMSMessageID等。
消息頭
消息頭 |
由誰設置 |
JMSDestination |
send方法 |
JMSDeliveryMode |
send方法 |
JMSExpiration |
send方法 |
JMSPriority |
send方法 |
JMSMessageID |
send方法 |
JMSTimestamp |
send方法 |
JMSCorrelationI |
客戶 |
JMSReplyTo |
客戶 |
JMSType |
客戶 |
JMSRedelivered |
JMS Provider |
屬性
除了消息頭中定義好的標準屬性外,JMS 提供一種機制增加新屬性到消息頭中,
這種新屬性包含以下幾種:
1.應用需要用到的屬性;
2.消息頭中原有的一些可選屬性;
3. JMS Provider需要用到的屬性。
標準的 JMS 消息頭包含以下屬性:
屬性名 |
描述 |
JMSDestination |
消息發送的目的地 |
JMSDeliveryMode |
傳送模式,有兩種模式: PERSISTENT 和 NON_PERSISTENT,PERSISTENT 表示該消息一定要被送到目的地,否則會導致應用錯誤。 NON_PERSISTENT 表示偶然丟失該消息是被允許的,這兩種模式使開發者可以在消息傳送的可靠性和吞吐量之間找到平衡點。 |
JMSExpiration |
消息過期時間,等于 Destination 的 send 方法中的 timeToLive 值加上發送時刻的 GMT 時間值。如果 timeToLive值等于零,則 JMSExpiration 被設為零,表示該消息永不過期。如果發送后,在消息過期時間之后 消息還沒有被發送到目的地,則該消息被清除。 |
JMSPriority |
消息優先級,從 0-9 十個級別,0-4 是普通消息, 5-9 是加急消息。JMS 不要求 JMS Provider 嚴格按照這十個優先級發送消息,但必須保證加急消息要先于普通消息到達。 |
JMSMessageID |
唯一識別每個消息的標識,由 JMS Provider 產生。 |
JMSTimestamp |
一個消息被提交給 JMS Provider 到消息被發出的時間。 |
JMSCorrelationI |
用來連接到另外一個消息,典型的應用是在回復消息中連接到原消息。 |
JMSReplyTo |
提供本消息回復消息的目的地址 |
JMSType |
消息類型的識別符 |
JMSRedelivered |
如果一個客戶端收到一個設置了 JMSRedelivered 屬性的消息,則表示可能客戶端曾經在早些時候收到過該消息,但并沒有簽收(acknowledged)。 |
消息體
JMS API 定義了 5種消息體格式,也叫消息類型,可以使用不同形式發送接收數據并可以兼容現有的消息格式。
消息類型 |
消息體 |
TextMessage |
java.lang.String對象,如 xml文件內容 |
MapMessage |
名/值對的集合,名是 String對象,值類型可以是 Java任何基本類型 |
BytesMessage |
字節流 |
StreamMessage |
Java中的輸入輸出流 |
ObjectMessage |
Java中的可序列化對象 |
Message |
沒有消息體,只有消息頭和屬性 |
PTP模型
PTP(Point-to-Point)模型是基于隊列的,生產者發消息到隊列,消費者從隊列接收消息,隊列的存在使得消息的異步傳輸成為可能。和郵件系統中的郵箱一樣,隊列可以包含各種消息,JMS Provider 提供工具管理隊列的創建、刪除。JMS PTP 模型定義了客戶端如何向隊列發送消息,從隊列接收消息,瀏覽隊列中的消息。
JMS PTP 模型中的主要概念和對象:
名稱 |
描述 |
ConnectionFactory |
客戶端用 ConnectionFactory 創建 Connection 對象。 |
Connection |
一個到 JMS Provider 的連接,客戶端可以用 Connection 創建 Session 來發送和接收消息。 |
Session |
客戶端用 Session 創建 MessageProducer 和 MessageConsumer對象。如果在 Session 關閉時,有一些消息已經被收到,但還沒有被簽收 (acknowledged),那么,當消費者下次連接到相同的隊列時,這些消息還會被再次接收。 |
Destination |
(Queue客戶端用 Session 創建 Destination 對象。此處或 TemporaryQueue)的目標為隊列,隊列由隊列名識別。臨時隊列只能由 創建它的 Connection 所創建的消費者消費,但是任何生產者都可向臨時隊列發送消息。 |
MessageProducer |
客戶端用 MessageProducer 發送消息到隊列。 |
MessageConsumer |
客戶端用 MessageConsumer 接收隊列中的消息,如果用戶在 receive方法中設定了消息選擇條件,那么不符合條件的消息會留在隊列中,不會被接收到。 |
|
|
Reliability |
可靠性, 隊列可以長久地保存消息直到消費者收到消息。消費者不需要因為擔心消息會丟失而時刻和隊列保持激活的連接狀態,充分體現了異步傳輸模式的優勢。 |
Pub/Sub模型
JMS Pub/Sub 模型定義了如何向一個內容節點發布和訂閱消息,這些節點被稱作主題(topic)。主題可以被認為是消息的傳輸中介,發布者(publisher)發布消息到主題,訂閱者(s
ubscribe) 從主題訂閱消息。主題使得消息訂閱者和消息發布者保持互相獨立,不需要
接觸即可保證消息的傳送。
JMS Pub/Sub 模型中的主要概念和對象:
名稱 |
描述 |
subscription |
訂閱 消息訂閱分為非持久訂閱(non-durable subscription)和持久訂閱(durable subscrip-tion),非持久訂閱只有當客戶端處于激活狀態,也就是和 JMS Provider 保持連接狀態才能收到發送到某個主題的消息,而當客戶端處于離線狀態,這個時間段發到主題的消息將會丟失,永遠不會收到。持久訂閱時,客戶端向 JMS 注冊一個識別自己身份的 ID,當這個客戶端處于離線時,JMS Provider 會為這個 ID 保存所有發送到主題的消息,當客戶再次連接到 JMS Provider時,會根據自己的 ID 得到所有當自己處于離線時發送到主題的消息。 |
ConnectionFactory |
客戶端用 ConnectionFactory 創建 Connection 對象。 |
Connection |
一個到 JMS Provider 的連接,客戶端可以用 Connection 創建 Session 來發送和接收消息。 |
Session |
客戶端用 Session 創建 MessageProducer 和 MessageConsumer對象。它還提供持久訂閱主題,或使用 unsubscribe 方法取消消息的持久訂閱。 Destination(Topic客戶端用 Session 創建 Destination 對象。此處和 TemporaryTopic)的目標為主題,主題由主題名識別。臨時主題只能由 創建它的 Connection所創建的消費者消費。臨時主題不能提供持久訂閱功能。JMS 沒有給 |