實現了JMS規范的消息系統,該系統還提供必須的用于管理和控制全方位的功能,如這里的ActiveMQ。
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
這是客戶端用來創建同JMS服務提供者之間的連接的對象。
這個對象是客戶端用來指明消息被發送的目的地以及客戶端接收消息的來源。被管理的對象一般被管理員放在JNDI名字空間中,通常在JMS客戶端應用的文檔中說明它所需要的JMS被管理對象,以及應以何種JNDI名字來提供這些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服務提供者應當將消息監聽器拋出異常的客戶端標記為“可能的障礙”。
用于在客戶端之間進行通訊的消息,消息系統的核心當然是消息。JMS 為不同類型的內容提供了幾種消息類型,但所有消息都是從 Message 接口派生出來的。
消息類型 | 說明 | 常用方法概覽 |
TextMessage | 文本消息 | getText,setText |
MapMessage | 映射消息 | setString,getString |
BytesMessage | 字節消息 | writeBytes,readBytes |
StreamMessage | 流消息 | writeString,readString |
ObjectMessage | 對象消息 | setObject,getObject |
表 常用消息類
Message 分為三個組成部分:
是一組標準字段,客戶機和提供者都用它們來標識和路由消息。
提供了一個給消息添加可選標題字段的實用工具。如果應用程序需要用標準標題字段沒有提供的方法對消息進行歸類或分類,那么可以為消息添加一個屬性來實現這 種歸類和分類;提供了 setProperty(...) 和 getProperty(...) 方法來設置和獲得各種 Java 類型的屬性,其中包括 Object。JMS 定義了提供者可以選擇性提供的一組標準屬性。
包含將發送到接收應用程序的內容。每一個消息接口都專用于它所支持的內容類型。
下面列出了 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 程序,程序不知道消息的接收者是誰;由提供者在接收過程中設置。
新聞熱點
疑難解答