BEA WebLogic Server (WLS)是使用最廣泛的J2EE
應(yīng)用服務(wù)器,對于大多數(shù)企業(yè)類情形來說,它一直是最有吸引力的平臺。
作為對J2EE 1.3支持的一部分, Java消息服務(wù)(JMS)已嵌入在WLS之內(nèi)。它的實(shí)現(xiàn)利用了很多WLS的嵌入式特性,比較直觀易懂。對于WLS這樣的主流產(chǎn)品而言,實(shí)現(xiàn)中等規(guī)模的JMS確實(shí)是很有價值的。
盡
管新增了內(nèi)嵌的JMS,WLS仍然保留著多樣性,可擴(kuò)展性已及實(shí)用性,即除了提供本地的功能以外,也對第三方解決復(fù)雜消息的方案提供支持。如,當(dāng)有多種應(yīng)
用服務(wù)器,C客戶端或者是非Java遺留應(yīng)用參與其中時,就會要求解決方案覆蓋較多的平臺;如果有象存儲客戶端或支持大容量消息這些特殊要求時,專門的解
決方案可能更好。如果對經(jīng)由集群,路由及錯誤恢復(fù)(failover)等的擴(kuò)展性、實(shí)用性要求非常高,則企業(yè)系統(tǒng)設(shè)計師必須向?qū)iT的消息服務(wù)供應(yīng)商尋求解
決方案。
應(yīng)用第三方JMS于高度擴(kuò)展的、面向關(guān)鍵任務(wù)的系統(tǒng)有很多優(yōu)點(diǎn),尤其當(dāng)有Enterprise JavaBean(EJB) 和XA
Container-Managed Transaction (CMT) 參與系統(tǒng)時,與僅僅從消息隊(duì)列取入取出的配置相比,它能夠進(jìn)行更復(fù)雜的處理。這個問題的提出主要基于兩個方面的考慮:一.
WLS 6.x 中實(shí)現(xiàn)Java Transaction API(JTA) 和 Java Transaction Service
(JTS) 的方式; 二. JMS和J2EE應(yīng)用服務(wù)器在運(yùn)行階段和開發(fā)階段相互關(guān)聯(lián)的問題。對第一點(diǎn)來說,與JMS供應(yīng)商合作是必須的解決方案(除非JMS將其內(nèi)部交易API公開-read:open
source)。對第二點(diǎn)來說,一個完整的解決方案吸引各種各樣的設(shè)計模式對JMS供應(yīng)商提供的工具進(jìn)行補(bǔ)充。
本文探討了第三方JMS 服務(wù)與WLS的集成,并且提出了經(jīng)由Sonic Software實(shí)現(xiàn)SonicMQ WLSAdapter從而解決前面所述兩個問題的方法。我們將回顧SonicMQ
JMS實(shí)現(xiàn)XA 交易的方法以及與非標(biāo)準(zhǔn)的WLS JTA之間建立映射的途徑,并進(jìn)一步演示了圍繞客戶端連接,裝載JNDI,異常處理,以及復(fù)雜EJB交互等所有相關(guān)問題的處理辦法。
WLS XA 交易與第三方JMS
支持Global Transaction(XA)或者CMT,通常意味著要處理特殊的、復(fù)雜的問題。當(dāng)WLS EJB利用其它JMS產(chǎn)品發(fā)送或接收消息,并且雙方都試圖以正常方式參與交易時,經(jīng)常會以失敗告終。這是因?yàn)閃LS
6.x 的JTA 和JTS是以非標(biāo)準(zhǔn)方式實(shí)現(xiàn)的。
按照J(rèn)MS規(guī)范所述,JMS提供者必須遵從JTA的規(guī)范,在創(chuàng)建和實(shí)用XA資源,即XAConnectionFactory, XAConnection
和XASeesion對象時應(yīng)該符合JTA的標(biāo)準(zhǔn)。同樣地,由XASeesion對象直接提供XAResourec對象時,JMS也必須符合JTA的標(biāo)準(zhǔn)(有關(guān)詳細(xì)情況請參考JMS1.0.2.b規(guī)范第八章
http://java.sun.com/products/jms/docs.html)。
假設(shè)所有第三方的JMS產(chǎn)品都符合這些標(biāo)準(zhǔn),那么它們也會期望作為JMS客戶端的應(yīng)用服務(wù)器完全遵從JMS規(guī)范,從而保證與XA兼容的操作能夠順利完成。WLS在處理XA交易中有四個方面的問題。
1. 沒有XAConnectionFactory, XAConnection 或者說 XASession
當(dāng)J2EE應(yīng)用服務(wù)器設(shè)置XA交易時,它期望利用外部JMS提供的XAQueueConnectionFactory 或者是XATopicConnectionFactory對象創(chuàng)建XAConnection和XASession對象。而WLS僅僅創(chuàng)建了JMS
連接和會話對象,因此,XA交易所指定的步驟和第八章所提出的規(guī)范并未實(shí)現(xiàn)。
2. 從未啟用XAResource
XA
交易的實(shí)現(xiàn)必須經(jīng)由XAResource開始。由于WLS沒有利用第三方提供的XAConnectionFActory對象,因此也就無從取得
XAResource對象了。這樣在消息驅(qū)動bean的情況下,本來應(yīng)該在應(yīng)用服務(wù)器的控制之下自動生成的外部XAResource對象也就從未實(shí)際進(jìn)入
CMT。同樣,會話bean也不能直接調(diào)用XAResource,XAResource無法在此處創(chuàng)建。
3. 專有的會話接口
WLS要求外部JMS的會話對象要實(shí)現(xiàn)一個指定的專門接口-weblogic.jms.extensions.MDBTransaction。該接口包含
一個方法associateTransaction(),WLS將在CMT調(diào)用這個方法進(jìn)入JMS交易管理器。由于這個接口是非標(biāo)準(zhǔn)的,第三方的JMS供
應(yīng)商必須包含一個適配器才能實(shí)現(xiàn)它。WLS會在內(nèi)部檢查會話對象是否支持該接口,如果不是,則容器會扔出一個異常。
4. XA交易分支未被串行化
按照J(rèn)TA規(guī)范,所有XA交易的分支必須以串行的方式進(jìn)行。但WLS是以另一種方式對交易分支進(jìn)行管理的,它允許由外部交易管理器提供給容器的第二個交易
分支在其它交易分支沒有完成之前即開始進(jìn)行。這種情況的發(fā)生是由于在WLS中,交易的開始分支和結(jié)束分支分屬于不同的線程。“開始”線程的動作已經(jīng)完成,
允許下一個交易分支開始,而此時第一個交易分支的“結(jié)束”動作還沒有完成。兼容JMS1.0.2的產(chǎn)品期望XA交易分支能夠遵循JTA的規(guī)范,以串行的次
序執(zhí)行,會認(rèn)為任何重疊執(zhí)行的交易分支都違反了JTA協(xié)議。因此,當(dāng)發(fā)生重疊交易時,依照J(rèn)MS的實(shí)現(xiàn)將扔出異常,除非JMS供應(yīng)商提供非標(biāo)準(zhǔn)的實(shí)現(xiàn)作為
變通。
進(jìn)入WebLogic Server Adapter (WLSAdapter)
盡管有這些問題存在,想加入WebLogic 市場的第三方JMS供應(yīng)商對于提供集成方案仍然具有很明確的目標(biāo)。大部分的供應(yīng)商通過包含適配器來彌補(bǔ)JMS
第八章的規(guī)則與WLS現(xiàn)有版本的“isws”特性之間的差異。適配器的實(shí)現(xiàn)非常引人矚目,不僅在于它們保證了XA功能的穩(wěn)定性,而且也在于它們?nèi)绾翁峁┮涣鞯模蓴U(kuò)展的解決方案。
SonicMQ是先進(jìn)的企業(yè)消息平臺,從Sonic Software 到WLSAdapter的方案解決了WLS和SonicMQ之間的集成問題。本方案的實(shí)現(xiàn)也涉及到其它重
要的集成難題,包括:
1. 客戶端自動連接和JNDI裝載。
2. 在開發(fā)階段測試異常處理邏輯時,促進(jìn)錯誤的發(fā)生。
3. 為復(fù)雜的JMS結(jié)構(gòu)提供穩(wěn)定的設(shè)計模板。
XA交易集成
應(yīng)用服務(wù)器提供XA交易功能且支持與第三方JMS的合作,必須具有下述能力:
1. 創(chuàng)建并管理JMS連接和會話。
2. 創(chuàng)建并管理XAConnection和XASession。
3. 啟用XAResource。
WLS能夠創(chuàng)建并管理JMS連接和會話,但無法創(chuàng)建XA交易和啟用XAResource。為了解決這個問題,WLSAdapter對所有的XAConnectionFactories,
XAConnection, XASession 和XAResource進(jìn)行創(chuàng)建和管理。
WLSAdapter
創(chuàng)建XASession時,它會同時在JVM內(nèi)創(chuàng)建一個單獨(dú)的XAResource
對象(稱為singleton),在每個XA交易進(jìn)行時與WLS的交易管理器聯(lián)系。在JMS交易管理器內(nèi)提供的實(shí)際的XAResource,由
WLSAdapter創(chuàng)建,并以singleton注冊,反過來將代理所有的WLS交易管理器調(diào)用合適的SonicMQ
XAResource。適配器在內(nèi)部管理所有的SonicMQ
XA分支。在消息驅(qū)動bean(MDB)的情況下,WLSAdapter會對每個交易自動啟用XAResource,而會話bean會通過WLS
TxHelper,javax.transaction.Transaction
txn=weblogic.transaction.TxHelper.getTransaction(),顯式啟用XAResource
(通過直接調(diào)用啟用方法:txn.enlistResource(myXAResource)。
這樣做的效果相當(dāng)于JMS適配器為WLS交易管理器提供了一個小型交易管理器作為單獨(dú)的資源參與交易。由于針對WLS交易管理器的XAResource已能夠獲得,因此解決了前兩個問題。
WLSAdapter
解決第三個問題用的是實(shí)現(xiàn)BEA專有接口-MDBTransaction的方法,在其會話對象中,在MDB交易時利用
associateTransaction()方法觸發(fā)自動啟用方式。由于方法是在適配器的會話對象中實(shí)現(xiàn)的,因此WLS不再扔出異常。
最
后,WLSAdapter解決第四個問題是通過對XA交易分支進(jìn)行管理以便確保它們的串行次序。當(dāng)WLS允許交易分支重疊時它先將SonicMQ的異常存
儲在緩存中,并將重疊交易分支控制著不執(zhí)行,直到前一個交易完成以后,再讓下一個交易分支開始進(jìn)行。異常被屏蔽,分支重疊被避免,XA交易與JTA規(guī)范達(dá)
到一致。
利用SonicMQ的WLSAdapter,解決了所有WLS與XA兼容的問題,為企業(yè)類JMS提供了一個完整的遵從JTA全局事務(wù)協(xié)議的解決方案。
集成方面的其它挑戰(zhàn)
運(yùn)行階段和開發(fā)階段的考慮
引入適配器,為增強(qiáng)企業(yè)解決方案的穩(wěn)定性,加入增值特性提供了一個機(jī)會。主要的考慮包括運(yùn)行時針對代理或連接失敗自動重新建立連接;為測試應(yīng)用級異常控制提供工具(尤其是連接和交易級上的恢復(fù)邏輯)。
客戶端自動重連
重建連接和錯誤恢復(fù)對任何大型的分布式應(yīng)用來說都是非常重要的。WebLogic 和SonicMQ都提供了集群和重新連接的功能。圖一是一個典型的WebLogic集群配置示意圖,該集群擁有兩臺服務(wù)器。
圖一 典型的集群配置

集群內(nèi)的任何WLS都可以訪問Topic A 和 Topic B。但是,主題(topic)必須提前創(chuàng)建,主題信息與本地一個專門的服務(wù)器相連。在事件實(shí)例A繼續(xù)進(jìn)行過程中,信息會被導(dǎo)往集群內(nèi)的其它服務(wù)器,Topic
A 就不再會被訪問到了。
圖二演示了WebLogic 集群與SonicMQ集群共同工作的情形,由于利用了WLSAdapter,因而具備了重建連接的功能。

在
本例中,無論哪一個WLS實(shí)例失敗,通過SonicMQ,所有的主題都保持有效。另外,如果任一個SonicMQ代理器失敗,所有信息將被自動恢復(fù)到備份
服務(wù)器或服務(wù)器上,主題信息并不會丟失。如果在SonicMQ內(nèi)利用WLSAdapter,則主題能夠被動態(tài)創(chuàng)建,信息也可以在JMS集群之內(nèi)共享。
在第一個例子中(沒有使用WLSAdapter),要想重新建立連接,則當(dāng)代理器失敗時,EJB中的消息產(chǎn)生者或者同步的消息使用者必須在應(yīng)用邏輯內(nèi)捕捉異常的發(fā)生,顯式的重新建立連接,重新構(gòu)建所有的會話對象。
WLS確實(shí)在MDB內(nèi)重新建立了連接,但監(jiān)聽器無法重建,因此有可能丟失消息。由WLSAdapter提供的解決方案如下:
1. 對用戶來說,連接失敗被完全屏蔽。
2. 連接重建依賴于URL列表。
3. 確保會話對象以及消息的產(chǎn)生者和使用者都被重新創(chuàng)建。
由于連接失敗和連接重建對用戶和業(yè)務(wù)邏輯是完全透明的,因此開發(fā)人員在編寫代碼,管理連接重建時是完全自由的。
故障插入點(diǎn)
WLSAdapter能夠插入故障點(diǎn)以便進(jìn)行程序跟蹤和分析。這樣做的目的主要是著眼于解決開發(fā)階段的棘手問題-集成測試,即引入可控制的,但是是實(shí)際的故障,以便測試異常捕捉路徑。WLSAdapter
提供了兩種類型的故障插入:連接失敗故障和方法調(diào)用故障。
連接失敗故障
連接失敗故障使應(yīng)用在指定的方法內(nèi)暫停。使用這種方法,開發(fā)人員可以在應(yīng)用執(zhí)行過程中,在外部采取某個動作從而在指定地方起作用。
如,想測試連接失敗或代理失敗時應(yīng)用的反應(yīng)情況,可以隨機(jī)地拔掉線纜或者關(guān)掉代理服務(wù)器。這樣做雖然可以產(chǎn)生測試實(shí)例,但它們無法可靠地再現(xiàn)。利用
SonicMQ
WLSAdapter,能夠在某個特殊的方法執(zhí)行過程中,如:MDB中的onMessage()方法,強(qiáng)制連接失敗發(fā)生,從而孤立故障點(diǎn)。當(dāng)方法被調(diào)用
時,適配器將使應(yīng)用暫停,此時,您可以強(qiáng)制代理連接斷開,模擬故障情況。當(dāng)故障點(diǎn)被釋放以后,應(yīng)用的后續(xù)執(zhí)行情況將揭示異常邏輯應(yīng)付故障的情形。
方法執(zhí)行故障
方法執(zhí)行故障在設(shè)計思想上與前面的很相似,但它只強(qiáng)制特定的方法扔出一個異常,而不要求開發(fā)人員的干預(yù)(諸如殺死代理服務(wù)器或拔掉線纜等)。當(dāng)設(shè)置了方法的故障點(diǎn)以后,程序在執(zhí)行到指定的方法時,就會暫停;此時會出現(xiàn)選擇:是讓方法扔出異常還是繼續(xù)正常執(zhí)行。
有10種辦法能夠用以設(shè)置連接故障和方法故障。其中的5種是用于JMS方法,其它的用于XA交易。應(yīng)用只需要在WLSAdapter中設(shè)置故障點(diǎn),執(zhí)行有問題的程序和方法即可,無需在應(yīng)用代碼中嵌入臨時測試邏輯語句。表一列出了在JMS和XA中有可能設(shè)置故障點(diǎn)的方法。
在WebLogic使用故障點(diǎn)插入非常簡單,只要將WLSAdapter包放入WebLogic 域啟動的類路徑(classpath),并在應(yīng)用服務(wù)器的啟動標(biāo)志中加入下列內(nèi)容:
-Dsonicsw.WLSAdapter.Test.DoFail=true
-Dsonicsw.WLSAdapter.Test.FailType=%1
-Dsonicsw.WLSAdapter.Test.FailPoint=%2
參數(shù)%1是“ConnectionDrop”或者是“MethodFailure”;參數(shù)%2代表表1中的某個方法。
表三

企業(yè)級設(shè)計模式
先進(jìn)的交易設(shè)計實(shí)現(xiàn)模版可以作為增值特性包含在適配器包之中。使用JMS的企業(yè)級EJB通常會要求若干個bean之間以交易的方式進(jìn)行交互。這些復(fù)雜的情形使得為保證穩(wěn)定性而做的聰明構(gòu)造和為擴(kuò)展性而設(shè)計的會話緩沖池成為必要。
例
如,一般的環(huán)境可能會要求MDB作為使用者對用于RFP的Pub/Sub
主題進(jìn)行監(jiān)聽。當(dāng)RFP消息到達(dá)時,它可能需要將文檔經(jīng)由實(shí)體bean存入本地數(shù)據(jù)庫;會話bean將生成響應(yīng)信息并經(jīng)由點(diǎn)對點(diǎn)隊(duì)列發(fā)送給請求者。在吞吐
量很大的環(huán)境中,向外發(fā)送的隊(duì)列可能會出于擴(kuò)展性的考慮將會話bean放入緩沖池中。在這種情況下,MDB,實(shí)體bean,和會話bean都成為單個交易
的組成部分,兩個兩個與JMS交易管理器進(jìn)行交易。
WLSAdapter完全解決了圍繞著企業(yè)級的這些問題。它將預(yù)制的代碼設(shè)計樣板包含在里面,這些樣板支持多個bean之間進(jìn)行交互。解決方案為消息的生產(chǎn)者和使用者展示了一個穩(wěn)定的、輕便的、利用無狀態(tài)會話緩沖池機(jī)制的環(huán)境。
未來展望
Sonic WLSAdapter中包含5個主要的JMS交易設(shè)計模式(參看圖三),它們是:
1. 消息驅(qū)動bean
2. 消息驅(qū)動bean路由器
3. 消息產(chǎn)生bean
4. 消息使用bean
5. 消息使用bean路由器
圖三

結(jié)論
在本文的第二部分,我們會描述在WLS中,利用SonicMQ和WLSAdapter作為JMS解決方案的部分設(shè)計模式的實(shí)現(xiàn)。具體的實(shí)現(xiàn)將會涉及到:
1. 消息驅(qū)動bean (與隊(duì)列監(jiān)聽器)
2. 消息驅(qū)動bean (與主題監(jiān)聽器和連接重建)
3. 消息使用bean
4. 消息產(chǎn)生bean(與JMS交叉域和連接重建)
我們將對前述的例子使用多個bean之間利用RFI/RFP進(jìn)行會話的組合設(shè)計模式。
說明:
提出了這么多問題,可能會有人問:WebLogic 是如何將JMS嵌入其中并運(yùn)行的?它又是如何通過Sun的J2EE 1.3
CTS的?答案來自兩個方面:第一,Sun CTS
只從API級別證實(shí)其遵從規(guī)范,并沒有對實(shí)現(xiàn)進(jìn)行規(guī)范,也就意味著很多內(nèi)部功能是靈活的。這也引出了第二個答案:嵌入的JMS與WLS容器的其它部分共享
交易管理器。由于只有一個交易管理器對交易進(jìn)行處理,因此WLS能夠在自己的環(huán)境下(以非標(biāo)準(zhǔn)的方式)進(jìn)行所有的XA集成,同時又與CTS
API級別的要求相符合。