天天看點

深入淺出JMS(二)——JMS的組成

JMS Provider

      實作了JMS規範的消息系統,該系統還提供必須的用于管理和控制全方位的功能,如這裡的ActiveMQ。

Administered Objects

      Administered Objects是預先配置的JMS對象,由系統管理者為使用JMS的用戶端建立,如ConnectionFactory、Destination。JMS被管理的對象是包含JMS配置資訊的對象,這些對象由JMS管理者建立,并且最終由JMS用戶端使用。

      由于有很多JMS消息系統,它們的底層實作技術各不相同,比如Sun MQ、IBM MQ、BEA MQ、Apache ActiveMQ,那麼如何使得JMS用戶端針對這些消息系統程式設計時能夠隔離這些産品的變化而具有跨平台特性呢?就是通過定義被管理的對象來實作。被管理的對象是由管理者通過使用JMS系統提供者的管理工具建立和定制,然後被JMS用戶端使用。JMS用戶端通過接口來調用這些被管理的對象,進而具備跨平台特性。

      主要有兩個被管理的對象:ConnectionFactory、Destination

ConnectionFactory

      這是用戶端用來建立同JMS服務提供者之間的連接配接的對象。

Destination

      這個對象是用戶端用來指明消息被發送的目的地以及用戶端接收消息的來源。被管理的對象一般被管理者放在JNDI名字空間中,通常在JMS用戶端應用的文檔中說明它所需要的JMS被管理對象,以及應以何種JNDI名字來提供這些JMS被管理對象。

JMS用戶端

      這些用戶端程式通過使用JMS提供的API,來建立發送和接收消息的Java語言程式,即消息生産者和消息消費者。

消息生産者

      用戶端使用MessageProducer向目的地發送消息。用Queue或者Topic對象作為參數來調用session對象的createProducer方法來建立MessageProducer。

      用戶端也可以選擇建立沒有目的地的生産者。這種情況下,目的地對象必須傳給每個發送操作。這種方式的一個典型用法就是生産者被用來發送回複請求時,使用請求的JMSReplyTo目的地。

      用戶端可指定由生産者發出的消息的預設的傳送模式、優先級、存活周期。每次用戶端建立MessageProducer,它就定義了新的消息系列,這些消息與以前發送的消息沒有順序關系。

消息消費者

      用戶端使用MessageConsumer接受來自于目的地的消息,MessageConsumer通過向Session的createConsumer方法傳遞Queue或Topic來建立。

      消費者可以被帶有消息選擇器的方式來建立。這使得用戶端可以限制傳送給消費者的消息必須同選擇器相比對。用戶端既可以同步擷取消費者的消息,也可以使提供者在消息到達時異步傳送消息。

Synchronous Delivery 同步傳送

      用戶端可以使用MessageConsumer的receive方法請求下一個來自于MessageConsumer的消息。Receive有幾種變化允許用戶端poll或者wait下一個消息。

Asynchronous Delivery 異步傳送

      用戶端可以注冊一個用MessageConsumer來實作JMS MessageListener接口的對象。當消息達到了消費者時,提供者通過調用監聽器的onMessage方法來傳送它們。可能監聽器會抛出RuntimeException異常,但是這主要考慮到的是用戶端程式錯誤。良好的監聽器應當捕捉這些異常并且嘗試将這些消息轉向發給一些應用指定的某些形式的“不可處理消息”的目的地。

監聽器抛出RuntimeException的結果取決于會話的确認模式:

n AUTO_ACKNOWLEDGE or DUPS_OK_ACKNOWLEDGE

      消息将被立即重發。在放棄之前的重發的次數取決于提供商。在這種情況下,JMSRedelivered 消息頭字段将設定在被重發的消息中。

n CLIENT_ACKNOWLEDGE

      監聽器的下一個消息将被傳送。如果用戶端希望是前面未确認的消息重新發送,它必須手工恢複會話。

n Transacted Session

      監聽器的下一個消息被發送,用戶端可以送出或者復原會話。(換句話說,RuntimeException不會導緻會話的自動復原)JMS服務提供者應當将消息監聽器抛出異常的用戶端标記為“可能的障礙”。

Message

      用于在用戶端之間進行通訊的消息,消息系統的核心當然是消息。JMS 為不同類型的内容提供了幾種消息類型,但所有消息都是從 Message 接口派生出來的。

消息類型 說明 常用方法概覽
TextMessage 文本消息 getText,setText
MapMessage 映射消息 setString,getString
BytesMessage 位元組消息 writeBytes,readBytes
StreamMessage 流消息 writeString,readString
ObjectMessage 對象消息 setObject,getObject

                                                         表 常用消息類

Message 分為三個組成部分:

Header

      是一組标準字段,客戶機和提供者都用它們來辨別和路由消息。

Properties

      提供了一個給消息添加可選标題字段的實用工具。如果應用程式需要用标準标題字段沒有提供的方法對消息進行歸類或分類,那麼可以為消息添加一個屬性來實作這種歸類和分類;提供了 setProperty(...) 和 getProperty(...) 方法來設定和獲得各種 Java 類型的屬性,其中包括 Object。JMS 定義了提供者可以選擇性提供的一組标準屬性。

Body

      包含将發送到接收應用程式的内容。每一個消息接口都專用于它所支援的内容類型。

下面列出了 Message 的每一個标題字段的名稱、它對應的 Java 類型和字段的描述:

JMSMessageID——類型為 string

      惟一辨別提供者發送的每一條消息。這個字段是在發送過程中由提供者設定的,客戶機隻能在消息發送後才能确定消息的 JMSMessageID。

      JMSDestination——類型為 Destination

      消息發送的 Destination,在發送過程中由提供者設定。

JMSDeliveryMode—類型為 int

      包含值 DeliveryMode.PERSISTENT 或者 DeliveryMode.NON_PERSISTENT。持久性消息被傳輸并且隻被傳輸一次,非持久性消息最多被傳輸一次。要知道“最多一次”包括根本不傳輸。非持久性消息在應用程式或者系統出故障時被提供者弄丢。是以要格外小心,確定持久性消息不受故障的影響。這比開銷通常被認為是發送持久性消息方面的開銷,在決定消息的發送模式時,必須仔細考慮,在可靠性和性能之間進行權衡。

JMSTimestamp——類型為 long

      提供者發送消息的時間,由提供者在發送過程中設定。

JMSExpiration——類型為 long

      消息失效的時間。這個值是在發送過程中計算的,是發送方法的生存時間(time-to-live)值和目前時間值的和。提供者不應發送過期的消息。值 0 表明消息不會過期。

JMSPriority——類型為 int

      消息的優先級,由提供者在發送過程中設定。優先級 0 的優先級最低,優先級 9 的優先級最高。

JMSCorrelationID——類型為 string

      通常用來連結響應消息與請求消息,由發送消息的 JMS 程式設定。響應來自另一個 JMS 程式的消息的 JMS 程式将正響應消息的 JMSMessageID 拷貝到這個字段中,這樣,正作出響應的程式就可以與它所發出的特定請求的響應相關聯。

JMSReplyTo—類型為 Destination

      請求程式用它來指出回複消息應發送的地方,由發送消息的 JMS 程式設定。

JMSType—類型為 string

      JMS 程式用它來指出消息的類型。一些提供者維護着一個消息類型倉庫,并用該字段引用倉庫中的定義類型,在這裡,JMS 程式不應該使用這個字段。

JMSRedelivered——類型為 boolean

      指出消息被過早地發送給了 JMS 程式,程式不知道消息的接收者是誰;由提供者在接收過程中設定。