運用JMS傳遞消息

有很多可選方法可以發送和確認接收消息,這就使開發人員可以靈活地在應用程序之間傳遞消息。
by Peter Varhol

企業中的消息傳遞(messaging)越來越被公認爲是創建企業應用程序的重要工具,對於創建應用程序本身來說,它的重要性也許不太明顯,但對於跨商業過程的應用和集成來說,其重要性就很大了。消息傳遞可以使我們在不能同步工作的應用程序或應用程序組件之間建立異步的通訊通道。建立這些類型的通道有什麼好處呢?企業可以得到更多的信息,而不需要創建新的底層架構和定製新的企業應用程序。

對於初學者來說,他們會對消息本身產生一個疑問:什麼是消息,它包括什麼?消息是完全由商業過程的需要定義的,而不是由一個運算單位定義的。一個消息可以是任何不連續的消息片段。它可以包含一個文件、或其它格式化的文件、一個文本請求或響應、或一條執行一個特定動作的指令。

Java Messaging Service(JMS)不會改變消息內容。它只是確保數據傳遞的一種方式。這種功能使JMS在用途和對不同用途的響應方面非常靈活(見圖1)。

圖1.
圖1. 確保消息的傳遞
Java 2 Platform、Enterprise Edition(J2EE)1.2提供了同步的消息傳遞,這就意味着,消息提供者和接收者在消息的內容和發送時間上必須達成一致。 從J2EE 1.3開始,Java就在其企業應用解決方案中集成了異步消息傳遞。JMS這個機制包括一個底層API用來訪問企業消息傳遞系統。JMS支持消息隊列和更現代的發佈-訂閱(publish-subscribe)消息傳遞方法。

企業中的用戶不太可能通過直接運用JMS來傳遞消息。作爲替代,集成軟件供應商將在一個較大的架構中運用JMS,這個架構包括應用程序、服務器、和提供更全面和更高級解決方案的消息提供者。企業將在這些架構中運用JMS,它可以提供高級的開發工具和應用程序管理支持。

那些開發和宣傳應用程序服務器(application server)的公司(IBM、BEA、Sun和Oracle)也都在專心研究運用JMS的消息傳遞技術,因爲將JMS作爲不同應用程序之間有效的通訊機制可能需要應用程序服務器的一些功能。特別的是,運用Enterprise Java Beans (EJBs) 的bean-driven的消息傳遞使應用程序服務器成爲該結構中的一個主要部分了。隨着消息傳遞成爲應用程序之間通訊的可行的解決方案,JMS將成爲應用程序服務器供應商的一個重要的考慮因素。

實際上,消息傳遞將更多地用來連接現有的應用程序和數據庫,而不是用來連接新組件。消息傳遞,或者更明確的消息傳遞架構,在以前遺留的系統、數據倉庫(data warehouse)、目的單一的應用程序、交易系統、甚至新的分佈式應用程序之間提供了連接,但它是典型的應用程序部署後的整合,而不是企業應用程序和數據策略的一個計劃了的部分(見工具條“JMS與Web Services的比較”)。

JMS與Web Services的比較

正如我們可能都知道的,Web services...
更多
下面是企業運用消息服務的方式:在大多數企業中,我們開發和部署應用程序是爲了解決特定的商業進程問題。隨着時間的推移,用戶發現,如果可以得到更多的數據,這些應用程序就會提供更多的商業信息。如果這些應用程序是用J2EE編寫的,那麼JMS就是在給商業問題提供一個技術解決方案的同時,保持應用程序完整性的一個自然的選擇了。即使一個或兩個應用程序都是在以前遺留的平臺上編寫的,如果企業是在計劃一個長期的Java策略,那麼JMS仍然有意義。

供應商運用JMS
作爲一種技術,消息傳遞已經出現好幾年了。諸如IBM MQSeries(現在的WebSphere MQ)和Microsoft MSMQ這樣的產品是基於交易的分佈式應用程序的消息傳遞提供者。但是,大多數情況下,發送機制是由企業開發人員決定的。這些消息傳遞提供者在很大程度上是爲另一個時代設計的,在這個時代中,一個交易客戶端或終端必須從大的遺留系統或數據倉庫發送和接收數據。

JMS下的架構有些不同。JMS的消息提供者組件是在應用程序服務器內部實現的。這麼做有一定的概念上的意義,因爲許多運用消息傳遞的應用程序也都在那個環境中運行。

然而,當消息傳遞所包含的應用程序是遺留的應用程序時,運用應用程序服務器就意味着,有些JMS功能不能用。相反,運用許多JMS解決方案中的專有功能就意味着,你被束縛到那個解決方案了,而沒有了跨平臺的可移植性。

BEA通過其標誌性的WebLogic應用程序服務器來支持JMS。WebLogic JMS實現了幾個JMS功能,包括一個可選的用來定義消息用戶服務器管理池的JMS工具。目前,WebLogic下的JMS不是集羣服務(clustered service),就是說,它不支持負載平衡(load balancing)或failover。

由於JMS不是個集羣服務,所以所有的客戶端都必須被配置,在一個集羣的特殊成員上運用JMS的相同的實例。用戶必須配置其中一個服務器,作爲JMS提供者。這種配置就意味着,屬性文件應該定義所有客戶端用來訪問JMS的connection factory,和JMS要用的連接池。總之,將消息提供者和使用者放在同一個服務器上可以增強應用程序的可靠性,因爲如果服務器壞了,那麼所有的消息就會丟失,每個人都必須從頭開始。

IBM的WebSphere系列也通過其WebSphere MQ產品(在添加了JMS 消息傳遞支持功能後,從MQSeries產品線重新命名的)實現了一個JMS工具。在2002年,該公司增加了對Java的支持,包括髮布-訂閱消息,並改進了性能和可擴展性。

有些供應商,如Spiritsoft,已經又前進了一步了,它將JMS用做構建更廣泛的應用程序集成架構的機制,企業開發人員可以用它來連接不同種類的企業系統。這些架構不需要包括應用程序服務器,但作爲替代,它可以提供一個獨立於平臺的方式,用Java來連接企業中的Java和本地應用程序。SpiritSoft的SpiritWave架構聲稱可以連接所有遺留的面向消息傳遞的中間件系統,在各種遺留的應用環境中運用JMS。

幾個供應商正將JMS整合到更全面的消息傳遞底層架構中。例如,Ashnasoft的AshnaMQ包括對JMS 1.1的支持,它可以用於實時Web、無線、Microsoft .Net和Java客戶端。AshnaMQ的管理工具可以動態地創建連接和sessions,它擁有多個消息發送者、接收者和瀏覽器,來發送、接收和查看消息。

同樣的,Sonic Software的SonicMQ可以從JMS、C、C++、COM和HTTP客戶端訪問到,並支持與應用程序服務器、其它消息傳遞系統、FTP和電子郵件的消息傳遞整合。Sonic的Dynamic Routing Architecture和集羣技術可以爲高級的可擴展性進行SonicMQ部署。

事實上,所有實現JMS的應用程序服務器供應商都至少提供了消息發送和處理功能。在許多情況下,供應商都擴展了消息確認或應用程序集羣這些領域中的標準。從部分程度上來說,對供應產品的專有擴展代表JMS標準還不成熟。還有很多消息傳遞的方面JMS都沒有考慮到,或者確認了這些方面但還沒實現。

JMS的一個重要方面是可以控制誰接收了什麼消息以及可以得到哪種消息發送保證,因爲並不是所有的消息的創建都是平等的。在有些情況下,消息是否到達目的地不是特別重要。例如,如果一個消息包括給某人發送的一個天氣預報,而由於這個人不在他或她的無線設備接收範圍內,那麼消息就不被認爲是重要的。

另一方面,有時侯,接收並處理一個消息是絕對很重要的。在商務活動中,就有必要確定是否接收並處理了一個訂單、信用確認或存貨訂購。有些情況下,在醫療保健、國防或太空探索中,如果出現故障,就會造成災難性的後果。

圖2.
圖2. Point-to-point消息傳遞
JMS可以完成各種任務。當然需要進行權衡。要確認接收到消息、允許複製消息或實現一個定製的確認工具會需要更復雜的代碼和更高的處理能力。然而,開發人員已習慣於進行這種權衡了,這種類型的功能可以使JMS用於很多不同的應用程序。

JMS給消息傳遞提供了兩種方法:point-to-point和publish-subscribe。每種方法都可以用於各種不同情況。Point-to-point消息對於每個消息都有一個接收者。接收者可以不同,但是隻有一個接收者來使用消息。這種方法可以用於獨特的交易,如在線購買(見圖2)。

圖3.
圖3. 訂閱者
另一方面,publish-subscribe認爲消息傳遞是針對多個訂閱者的。這種方法可以使多個用戶訂閱一個特殊的消息並接收那個消息,而不管其它訂閱者的數量是多少。消息在發送時,不是自動處理的;作爲替代,你可以認爲它被訂閱者接收了(見圖3)。

Javax.jms包中的不同機制實現了這些方法。在兩種情況下,起點都是Destination接口。Destination代表了一個消息傳遞通道,它是連接消息源和接收者的機制。對於point-to-point消息來說,接口Queue擴展了Destination。正如你所預料的,Queue將消息排列起來,按順序一次使用一個。Queue也需要指定消息的接收者,一個消息只有一個接收者。

對於publish-subscribe消息來說,接口Topic擴展了Destination。Topic可以使多個訂閱者接收到消息。接收者必須訂閱,就是說,採取一些行動來確保他們在這些消息的接收者名單上。

從概念上講,Destination不是個傳遞機制。它是一個有順序的列表,就像Queue這個名字的含義一樣。對於Queue接口來說,它就像一個隊列數據結構,可以讓接收者按順序使用消息。Topic也像一個隊列數據結構,不同的是,在所有的訂閱者都接收到消息後,它纔會從列表中去除。

消息提供者,通常是某種類型的應用程序,創建了消息並用Destination接口來放置它們等待發送。使用者,即消息接收者,讀取到消息,在Queue接口情況下,將消息從列表中去除。從概念上說,這個過程很簡單,只是將數據從一個應用程序傳遞到另一個應用程序。然而,細節並不是這麼簡單的。

打算將JMS用於應用程序的任何人都需要考慮消息傳遞、消息接收確認、組件故障和故障恢復方法。JMS提供了各種可選方法,需要我們進行權衡。Auto模式是確認接收的最簡單的形式,可以自動確認消息。運用auto模式就爲消息提供了一次性發送保證。列表1是運用autoacknowledgement接收JMS消息的一個例子。

作爲對比,在dupicates okay模式中,儘管消息仍可以自動確認,但在確認響應時間上就沒有保證了。當處理能力和帶寬可以進行確認時,消息就得到了確認。當確認是必要的時,這種方法很有用,但處理進一步的消息就不能依賴它了。列表2說明的是運用duplicates okay方法的一個實現例子。

第三種方法是client模式,在這種模式下,沒有自動確認。作爲替代,接收者負責給發送者提供確認。這種方法可以調整確認,所以它最滿足應用程序的需要。權衡點是,如果運用確認,確認必須在接收應用程序內實現,而不是用JMS提供的工具。代價是代碼很複雜,而且手動實現也需要資源。

JMS供應商提供的其它類型的確認在很大程度上是這些選項的變異形式。其它方法不是JMS的確定部分,所以運用它們有利也有弊。它們可以給你提供更適合你的應用程序需求的選擇方案,但是是以標準化和可移植性爲代價的。

從應用程序的立場來看,消息傳遞機制也有幾個可選方法。擁有多個可選方法是很重要的,因爲應用程序可能不僅需要確保消息的接收,也要確保完成處理消息。如果在消息被處理完前,應用程序或其硬件發生故障,可能就需要另一個機制來重新發送消息。

一個交易式的session可以使一個應用程序通過創建一個本地交易來接收消息。在這種方式下,接收的應用程序通過其功能(如在適當的時候提交交易,或在出現問題時回滾交易)來控制消息的發送。

你也可以用message-driven beans來控制消息的處理,運用container或noncontainer方法。Container方法可以使bean container監控交易是否成功。運用這種方法,bean指定部署描述符中的container,container根據它對應用程序的確認,來確定是否提交交易或回滾交易。

作爲選擇,bean也可以在container不參與的情況下監控交易是否成功。在這種情況下,監控必須是手動實現的。我們通過代碼來描述消息發送過程和交易是否提交或回滾。這種手動的方法再次以代碼複雜性爲代價提供了更高程度的靈活性。

JMS適合你的企業嗎?
在運用JMS時你應該考慮的第一個方面是你的應用程序是否接受基於消息的通訊。如果你已經運用了一個隊列結構,那麼你就可以運用JMS了。如果不是,那就問問自己,你是否有單獨的應用程序可以從交易中受益。你可能還沒有運用消息傳遞,但你可以將它作爲一個更長遠的目標來簡化商業進程或改進數據流。

一旦你確定了你的應用程序或進程可以利用JMS消息傳遞,那麼你就需要確定你是否有底層架構支持它。該底層架構包括用於網絡和應用程序服務器的硬件,以及對應用程序服務器的支持。同時,確定你對性能、消息傳遞、確認和故障的需求也是很重要的,而且要保證你選用的硬件和軟件支持這些需求。

JMS可以用於任何企業的各種應用程序。通過仔細設計和實現消息傳遞,基於交易的過程可以被擴展和改進。JMS提供了基於Java的消息傳遞,它支持這些目標,同時運用了Java技術和現有的計劃了的Java應用程序。它們的整合使JMS架構可以給應用集成項目提供實際的價值。


關於作者:
Peter Varhol是Compuware Corporation的一名技術傳播者。他的聯繫方式是[email protected]
發佈了35 篇原創文章 · 獲贊 1 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章