使用JMS隊列 |
|
Java消息發送服務(Java Messaging Service,JMS)是提供商無關的一套API,用于在程序間進行可靠的消息發送。在客戶端-服務器計算中,客戶端程序與服務器與服務器建立聯系并請求服務。相反,消息發送應用在相互協作的程序之間發送消息。有些程序(在所謂的“對等(peer-to-peer)”應用中)則相互之間直接交換信息(JXTA使用的就是這種模型)。 JMS提供了一個中間件消息代理(message broker),后者提供了程序間可靠的、事務性的消息發送。 雖然這些圖中顯示的消息提供者和消費者都是物理上的機器,實際上它們也可以是運行在一臺或者多臺機器上的相互協作的一些進程。 JMS提供者是一個程序,它實現了JMS公共接口中的JMS服務約定。J2EE平臺規范要求平臺實現包含一個JMS提供者。 大多數人都比較熟悉客戶端-服務器模型的消息發送,在這種模型中,客戶端程序與服務器建立聯系,請求服務、數據,或者同時請求服務和數據。相反,JMS提供了一種更豐富的消息發送模型,這種模型具有以下高級特性: 可靠的消息發送。當消息發送者正在發送消息時,消息接受者無需處于運行狀態。而是等等接受者下次做好準備時,再將消息發送到接受者手上。
JMS隊列術語 JMS使用消息隊列的概念來實現點到點的消息發送。在點到點的消息發送中,總是有一個明確的消息生產者和一個消息消費者。在點到點的消息發送中,與時間沒有多大的關系,除非消息發送者為消息定義了一個期限。消息接受這可以接收由消息生產者在過去任何一個時候發送的消息,即使在該消息被編入隊列時消息消費者沒有處于運行狀態。 JMS提供者是一個消息發送服務器,它負責處理消息的持久性、超時、重發、事務回滾以及由JMS提供的其他服務。對于J2EE SDK這種情況,JMS提供者是J2EE服務器程序的一部分。消息生產者發送對象到由JMS維護的一個隊列中。消息消費者則從該隊列接收消息,并發出確認,表示已經收到消息。 JMS規范定義了一些可用于在進程間發送消息的對象: JMS管理的對象。有兩種JMS管理的對象:目的地和連接工廠。這兩種對象都是由系統管理員通過環境管理工具創建的。 消息消費者。這是一種由JMS客戶端程序使用的、用于從一個目的地接收消息的對象。JMS客戶端程序從一個會話中獲取消息接受者對象。程序可以使用QueueReceiver這種類型的消息消費者對象來從一個隊列中接收消息。
J2EE參考實現預先配有一個隊列連接工廠(名為QueueConnectionFactory)和一個隊列(名為jms/Queue)。如果你使用的是JMS服務器,而不是參考實現,或者如果你想試著更改隊列連接工廠和/或隊列隊列的名稱,請參考配置服務器一節。 下面是通過一個JMS隊列發送消息的步驟。從示例程序TestQueue中抽出的代碼片段也穿插在這些步驟中。 通過按名字在JNDI中進行查找,獲得一個指向QueueConnectionFactory 的引用: protected static String qfactoryName =3.
3. 使用QueueSession創建一個QueueSender,將該隊列作為一個參數來傳遞。(QueueSender是QueueSession與某個特定隊列之間的一個關聯。):
4. 創建一個消息對象(Message的子類),然后使用QueueSender的發送方法將它們發送至目的地。示例程序從Session中獲得一個TextMessage對象。接著示例程序將每個程序參數打包到TextMessage 中,然后使用QueueSender將其發送至隊列。注意,同一個TextMessage 可以使用多次。
5.關閉QueueConnection。在try/finally程序塊的最后一條語句中關閉連接是一個好習慣。這一步很重要:忘記關閉 QueueConnections 將可能導致服務器上的資源泄漏:
}
$ java TestQueue send jms/queue/MyTestQueue a b c d
TestQueue程序按照以下步驟接收消息: 和2從一個消息隊列接收消息的起先兩步與發送消息是一樣的:先是查找連接工廠,再獲得一個QueueConnection,然后查找Queue。
if (m instanceof TextMessage) { 對QueueConnection的啟動方法的調用將告訴連接開始接收消息。QueueReceiver接收方法帶有一個參數,該參數表明了等待一條消息的毫秒數。如果消息沒有在規定時間內到達,該方法將返回null值。直到消息隊列在100毫秒的時間內都保持為空,程序才開始讀取和打印收到的消息。在try/finally程序塊的結尾有一個finally子句,該子句像前面例子中一樣地關閉QueueConnection。 要接收消息隊列中的消息,可以使用TestQueue程序,再帶上一個參數“recy”,例如: $ java TestQueue recv jms/queue/MyTestQueue
如果你使用的不是參考引用,或者你想更改隊列和/或隊列連接工廠的名字,你就需要通過使用平臺的管理工具配置JMS提供者。隊列或者連接工廠被創建之后,便留在服務器中,直到服務器重新啟動。有些平臺實現可能會為客戶端提供擴展API,以便程序化地創建目的地和連接工廠。 用來在J2EE SDK下創建受管理的對象的工具是。要配置服務器,需: 啟動應用服務器。 用消息隊列的實際名字替換<queuename> 。 由于連接工廠名QueueConnectionFactory被硬性地放在示例程序中,因此要告訴程序使用一個不同的連接工廠名,就必須修改源代碼,并且重新編譯。例如,在TestQueue.java中: // Change this variable's value to change the
j2eeadmin -addJmsFactory jms/MyQueueConnectionFactory 要列出連接工廠,使用: j2eeadmin -listJmsFactory 要列出目的地,使用: j2eeadmin -listJmsDestination 對于不是J2EE SDK的平臺,可以在該平臺上使用J2EE產品的部署工具來創建所需的消息隊列和連接工廠。
下載這些期的示例存檔。這個JAR文件包含了示例程序的完整源代碼,包括Java程序文件和HTML格式的文件。你可以使用命令jar xvf ttmar2003.jar 將示例jar中的內容解壓縮到你的工作目錄下。在運行示例程序前,要確保J2EE服務器正在運行。 多次運行示例程序。試著發送一些成批的消息,但是不接收這些消息,檢查一下輸出的順序。 這個示例程序為你試著使用JMS隊列提供了切入點。探索一下JMS接口使用的API。例如,可以更改一下程序,試著使用三種不同的接收方式。探索一下事務性的消息發送,或者試著發送各種類型的消息對象。JMS有許多特性,熟練使用它可以提高你的應用設計水平。 |