BEA WebLogic Server (WLS)是使用最廣泛的J2EE 應用服務器,對于大多數企業類情形來說,它一直是最有吸引力的平臺。

作為對J2EE 1.3支持的一部分, Java消息服務(JMS)已嵌入在WLS之內。它的實現利用了很多WLS的嵌入式特性,比較直觀易懂。對于WLS這樣的主流產品而言,實現中等規模的JMS確實是很有價值的。

盡 管新增了內嵌的JMS,WLS仍然保留著多樣性,可擴展性已及實用性,即除了提供本地的功能以外,也對第三方解決復雜消息的方案提供支持。如,當有多種應 用服務器,C客戶端或者是非Java遺留應用參與其中時,就會要求解決方案覆蓋較多的平臺;如果有象存儲客戶端或支持大容量消息這些特殊要求時,專門的解 決方案可能更好。如果對經由集群,路由及錯誤恢復(failover)等的擴展性、實用性要求非常高,則企業系統設計師必須向專門的消息服務供應商尋求解 決方案。

應用第三方JMS于高度擴展的、面向關鍵任務的系統有很多優點,尤其當有Enterprise JavaBean(EJB) 和XA Container-Managed Transaction (CMT) 參與系統時,與僅僅從消息隊列取入取出的配置相比,它能夠進行更復雜的處理。這個問題的提出主要基于兩個方面的考慮:一. WLS 6.x 中實現Java Transaction API(JTA) 和 Java Transaction Service (JTS) 的方式; 二. JMS和J2EE應用服務器在運行階段和開發階段相互關聯的問題。對第一點來說,與JMS供應商合作是必須的解決方案(除非JMS將其內部交易API公開-read:open source)。對第二點來說,一個完整的解決方案吸引各種各樣的設計模式對JMS供應商提供的工具進行補充。

本文探討了第三方JMS 服務與WLS的集成,并且提出了經由Sonic Software實現SonicMQ WLSAdapter從而解決前面所述兩個問題的方法。我們將回顧SonicMQ JMS實現XA 交易的方法以及與非標準的WLS JTA之間建立映射的途徑,并進一步演示了圍繞客戶端連接,裝載JNDI,異常處理,以及復雜EJB交互等所有相關問題的處理辦法。

WLS XA 交易與第三方JMS

支持Global Transaction(XA)或者CMT,通常意味著要處理特殊的、復雜的問題。當WLS EJB利用其它JMS產品發送或接收消息,并且雙方都試圖以正常方式參與交易時,經常會以失敗告終。這是因為WLS 6.x 的JTA 和JTS是以非標準方式實現的。
按照JMS規范所述,JMS提供者必須遵從JTA的規范,在創建和實用XA資源,即XAConnectionFactory, XAConnection 和XASeesion對象時應該符合JTA的標準。同樣地,由XASeesion對象直接提供XAResourec對象時,JMS也必須符合JTA的標準(有關詳細情況請參考JMS1.0.2.b規范第八章 http://java.sun.com/products/jms/docs.html)。

假設所有第三方的JMS產品都符合這些標準,那么它們也會期望作為JMS客戶端的應用服務器完全遵從JMS規范,從而保證與XA兼容的操作能夠順利完成。WLS在處理XA交易中有四個方面的問題。

1. 沒有XAConnectionFactory, XAConnection 或者說 XASession

當J2EE應用服務器設置XA交易時,它期望利用外部JMS提供的XAQueueConnectionFactory 或者是XATopicConnectionFactory對象創建XAConnection和XASession對象。而WLS僅僅創建了JMS 連接和會話對象,因此,XA交易所指定的步驟和第八章所提出的規范并未實現。

2. 從未啟用XAResource

XA 交易的實現必須經由XAResource開始。由于WLS沒有利用第三方提供的XAConnectionFActory對象,因此也就無從取得 XAResource對象了。這樣在消息驅動bean的情況下,本來應該在應用服務器的控制之下自動生成的外部XAResource對象也就從未實際進入 CMT。同樣,會話bean也不能直接調用XAResource,XAResource無法在此處創建。

3. 專有的會話接口

WLS要求外部JMS的會話對象要實現一個指定的專門接口-weblogic.jms.extensions.MDBTransaction。該接口包含 一個方法associateTransaction(),WLS將在CMT調用這個方法進入JMS交易管理器。由于這個接口是非標準的,第三方的JMS供 應商必須包含一個適配器才能實現它。WLS會在內部檢查會話對象是否支持該接口,如果不是,則容器會扔出一個異常。

4. XA交易分支未被串行化

按照JTA規范,所有XA交易的分支必須以串行的方式進行。但WLS是以另一種方式對交易分支進行管理的,它允許由外部交易管理器提供給容器的第二個交易 分支在其它交易分支沒有完成之前即開始進行。這種情況的發生是由于在WLS中,交易的開始分支和結束分支分屬于不同的線程。“開始”線程的動作已經完成, 允許下一個交易分支開始,而此時第一個交易分支的“結束”動作還沒有完成。兼容JMS1.0.2的產品期望XA交易分支能夠遵循JTA的規范,以串行的次 序執行,會認為任何重疊執行的交易分支都違反了JTA協議。因此,當發生重疊交易時,依照JMS的實現將扔出異常,除非JMS供應商提供非標準的實現作為 變通。

進入WebLogic Server Adapter (WLSAdapter)

盡管有這些問題存在,想加入WebLogic 市場的第三方JMS供應商對于提供集成方案仍然具有很明確的目標。大部分的供應商通過包含適配器來彌補JMS 第八章的規則與WLS現有版本的“isws”特性之間的差異。適配器的實現非常引人矚目,不僅在于它們保證了XA功能的穩定性,而且也在于它們如何提供一流的,可擴展的解決方案。

SonicMQ是先進的企業消息平臺,從Sonic Software 到WLSAdapter的方案解決了WLS和SonicMQ之間的集成問題。本方案的實現也涉及到其它重

要的集成難題,包括:

1. 客戶端自動連接和JNDI裝載。

2. 在開發階段測試異常處理邏輯時,促進錯誤的發生。

3. 為復雜的JMS結構提供穩定的設計模板。

XA交易集成

應用服務器提供XA交易功能且支持與第三方JMS的合作,必須具有下述能力:

1. 創建并管理JMS連接和會話。

2. 創建并管理XAConnection和XASession。

3. 啟用XAResource。

WLS能夠創建并管理JMS連接和會話,但無法創建XA交易和啟用XAResource。為了解決這個問題,WLSAdapter對所有的XAConnectionFactories, XAConnection, XASession 和XAResource進行創建和管理。

WLSAdapter 創建XASession時,它會同時在JVM內創建一個單獨的XAResource 對象(稱為singleton),在每個XA交易進行時與WLS的交易管理器聯系。在JMS交易管理器內提供的實際的XAResource,由 WLSAdapter創建,并以singleton注冊,反過來將代理所有的WLS交易管理器調用合適的SonicMQ XAResource。適配器在內部管理所有的SonicMQ XA分支。在消息驅動bean(MDB)的情況下,WLSAdapter會對每個交易自動啟用XAResource,而會話bean會通過WLS TxHelper,javax.transaction.Transaction txn=weblogic.transaction.TxHelper.getTransaction(),顯式啟用XAResource (通過直接調用啟用方法:txn.enlistResource(myXAResource)。

這樣做的效果相當于JMS適配器為WLS交易管理器提供了一個小型交易管理器作為單獨的資源參與交易。由于針對WLS交易管理器的XAResource已能夠獲得,因此解決了前兩個問題。

WLSAdapter 解決第三個問題用的是實現BEA專有接口-MDBTransaction的方法,在其會話對象中,在MDB交易時利用 associateTransaction()方法觸發自動啟用方式。由于方法是在適配器的會話對象中實現的,因此WLS不再扔出異常。

最 后,WLSAdapter解決第四個問題是通過對XA交易分支進行管理以便確保它們的串行次序。當WLS允許交易分支重疊時它先將SonicMQ的異常存 儲在緩存中,并將重疊交易分支控制著不執行,直到前一個交易完成以后,再讓下一個交易分支開始進行。異常被屏蔽,分支重疊被避免,XA交易與JTA規范達 到一致。

利用SonicMQ的WLSAdapter,解決了所有WLS與XA兼容的問題,為企業類JMS提供了一個完整的遵從JTA全局事務協議的解決方案。

集成方面的其它挑戰

運行階段和開發階段的考慮

引入適配器,為增強企業解決方案的穩定性,加入增值特性提供了一個機會。主要的考慮包括運行時針對代理或連接失敗自動重新建立連接;為測試應用級異??刂铺峁┕ぞ撸ㄓ绕涫沁B接和交易級上的恢復邏輯)。

客戶端自動重連

重建連接和錯誤恢復對任何大型的分布式應用來說都是非常重要的。WebLogic 和SonicMQ都提供了集群和重新連接的功能。圖一是一個典型的WebLogic集群配置示意圖,該集群擁有兩臺服務器。

圖一 典型的集群配置

集群內的任何WLS都可以訪問Topic A 和 Topic B。但是,主題(topic)必須提前創建,主題信息與本地一個專門的服務器相連。在事件實例A繼續進行過程中,信息會被導往集群內的其它服務器,Topic A 就不再會被訪問到了。

圖二演示了WebLogic 集群與SonicMQ集群共同工作的情形,由于利用了WLSAdapter,因而具備了重建連接的功能。

在 本例中,無論哪一個WLS實例失敗,通過SonicMQ,所有的主題都保持有效。另外,如果任一個SonicMQ代理器失敗,所有信息將被自動恢復到備份 服務器或服務器上,主題信息并不會丟失。如果在SonicMQ內利用WLSAdapter,則主題能夠被動態創建,信息也可以在JMS集群之內共享。

在第一個例子中(沒有使用WLSAdapter),要想重新建立連接,則當代理器失敗時,EJB中的消息產生者或者同步的消息使用者必須在應用邏輯內捕捉異常的發生,顯式的重新建立連接,重新構建所有的會話對象。

WLS確實在MDB內重新建立了連接,但監聽器無法重建,因此有可能丟失消息。由WLSAdapter提供的解決方案如下:

1. 對用戶來說,連接失敗被完全屏蔽。

2. 連接重建依賴于URL列表。

3. 確保會話對象以及消息的產生者和使用者都被重新創建。

由于連接失敗和連接重建對用戶和業務邏輯是完全透明的,因此開發人員在編寫代碼,管理連接重建時是完全自由的。

故障插入點

WLSAdapter能夠插入故障點以便進行程序跟蹤和分析。這樣做的目的主要是著眼于解決開發階段的棘手問題-集成測試,即引入可控制的,但是是實際的故障,以便測試異常捕捉路徑。WLSAdapter 提供了兩種類型的故障插入:連接失敗故障和方法調用故障。

連接失敗故障

連接失敗故障使應用在指定的方法內暫停。使用這種方法,開發人員可以在應用執行過程中,在外部采取某個動作從而在指定地方起作用。

如,想測試連接失敗或代理失敗時應用的反應情況,可以隨機地拔掉線纜或者關掉代理服務器。這樣做雖然可以產生測試實例,但它們無法可靠地再現。利用 SonicMQ WLSAdapter,能夠在某個特殊的方法執行過程中,如:MDB中的onMessage()方法,強制連接失敗發生,從而孤立故障點。當方法被調用 時,適配器將使應用暫停,此時,您可以強制代理連接斷開,模擬故障情況。當故障點被釋放以后,應用的后續執行情況將揭示異常邏輯應付故障的情形。

方法執行故障

方法執行故障在設計思想上與前面的很相似,但它只強制特定的方法扔出一個異常,而不要求開發人員的干預(諸如殺死代理服務器或拔掉線纜等)。當設置了方法的故障點以后,程序在執行到指定的方法時,就會暫停;此時會出現選擇:是讓方法扔出異常還是繼續正常執行。

有10種辦法能夠用以設置連接故障和方法故障。其中的5種是用于JMS方法,其它的用于XA交易。應用只需要在WLSAdapter中設置故障點,執行有問題的程序和方法即可,無需在應用代碼中嵌入臨時測試邏輯語句。表一列出了在JMS和XA中有可能設置故障點的方法。

在WebLogic使用故障點插入非常簡單,只要將WLSAdapter包放入WebLogic 域啟動的類路徑(classpath),并在應用服務器的啟動標志中加入下列內容:

-Dsonicsw.WLSAdapter.Test.DoFail=true
-Dsonicsw.WLSAdapter.Test.FailType=%1
-Dsonicsw.WLSAdapter.Test.FailPoint=%2

參數%1是“ConnectionDrop”或者是“MethodFailure”;參數%2代表表1中的某個方法。

表三

企業級設計模式

先進的交易設計實現模版可以作為增值特性包含在適配器包之中。使用JMS的企業級EJB通常會要求若干個bean之間以交易的方式進行交互。這些復雜的情形使得為保證穩定性而做的聰明構造和為擴展性而設計的會話緩沖池成為必要。

例 如,一般的環境可能會要求MDB作為使用者對用于RFP的Pub/Sub 主題進行監聽。當RFP消息到達時,它可能需要將文檔經由實體bean存入本地數據庫;會話bean將生成響應信息并經由點對點隊列發送給請求者。在吞吐 量很大的環境中,向外發送的隊列可能會出于擴展性的考慮將會話bean放入緩沖池中。在這種情況下,MDB,實體bean,和會話bean都成為單個交易 的組成部分,兩個兩個與JMS交易管理器進行交易。

WLSAdapter完全解決了圍繞著企業級的這些問題。它將預制的代碼設計樣板包含在里面,這些樣板支持多個bean之間進行交互。解決方案為消息的生產者和使用者展示了一個穩定的、輕便的、利用無狀態會話緩沖池機制的環境。

未來展望

Sonic WLSAdapter中包含5個主要的JMS交易設計模式(參看圖三),它們是:

1. 消息驅動bean

2. 消息驅動bean路由器

3. 消息產生bean

4. 消息使用bean

5. 消息使用bean路由器

圖三

結論

在本文的第二部分,我們會描述在WLS中,利用SonicMQ和WLSAdapter作為JMS解決方案的部分設計模式的實現。具體的實現將會涉及到:

1. 消息驅動bean (與隊列監聽器)

2. 消息驅動bean (與主題監聽器和連接重建)

3. 消息使用bean

4. 消息產生bean(與JMS交叉域和連接重建)

我們將對前述的例子使用多個bean之間利用RFI/RFP進行會話的組合設計模式。

說明:

提出了這么多問題,可能會有人問:WebLogic 是如何將JMS嵌入其中并運行的?它又是如何通過Sun的J2EE 1.3 CTS的?答案來自兩個方面:第一,Sun CTS 只從API級別證實其遵從規范,并沒有對實現進行規范,也就意味著很多內部功能是靈活的。這也引出了第二個答案:嵌入的JMS與WLS容器的其它部分共享 交易管理器。由于只有一個交易管理器對交易進行處理,因此WLS能夠在自己的環境下(以非標準的方式)進行所有的XA集成,同時又與CTS API級別的要求相符合。