Websphere MQ Everyplace 和 Websphere MQ內建實踐
1. 概述
IBM Websphere MQ Everyplace(MQe)是Websphere MQ(WMQ)産品家族系列中的一員。它是為輕量級的裝置而設計,例如電話、PDA、Palm和膝上型電腦等。本文将描述一個用MQe與WMQ內建移動裝置和企業内部系統的例子。
通過本文您将了解:
MQe基本概念和設計開發入門知識。 如何配置MQe Server和WMQ,使它們能夠通過網橋子產品互相通信。 如何開發MIDP環境下的MQe Client和應用程式。 最後,內建基于MIDP的MQe Client,MQe Server和WMQ。
您需要下面的軟體:
Windows 2000 Server (English) Websphere MQ Everyplace 2.0 Websphere MQ 5.3 for Windows Websphere Studio Device Developer 5.0 Websphere Business Integration Message Broker 5.0
2. MQe 簡介
MQe在Websphere MQ産品系列中的地位
IBM Websphere MQ産品家族可以分為三大類:(見圖一)
Websphere MQ Workflow:通過自動化的流程處理,簡化企業内部的應用內建。目前産品是Websphere MQ Workflow 3.4。 Websphere MQ Integrator:功能強大的消息代理軟體,提供實時,基于規則的智能化消息路由,消息格式轉化等功能。目前産品是WBI Message Broker 5.0和WBI Event Broker 5.0。 Websphere MQ Messaging:用可靠的消息傳遞機制,為大型伺服器和PC提供點對點連接配接,支援35種平台。目前産品是Webspher MQ 5.3和Websphere MQ Everyplace 2.0。
圖一Websphere MQ産品家族
MQ Workflow和MQ Integrator産品都是運作在MQ Messaging産品的基礎上。消息傳遞是基于隊列(Queue)和隊列管理器(Queue Manager)。隊列管理器管理所有的隊列,以及儲存在隊列内部的消息。應用程式連接配接隊列管理器(Local Queue Manager)來讀寫消息。如果要放一個消息到遠端的隊列(Remote Queue),消息是通過通道(Channel)傳輸到遠端的隊列管理器(Remote Queue Manager)。MQe和WMQ都是用類似的消息機制來傳遞消息。
MQe 擴充了WMQ的消息傳遞領域,它主要有下列幾個特點:
MQe不但支援手機,PDA等低端産品和移動裝置,還支援PC,伺服器和大型工作站。MQe可以在Palm OS、PocketPC、Windows、Linux、Unix、AIX等環境下運作,總共支援35種作業系統。 提供輕量級的消息傳遞機制。在網絡不穩定,帶寬限制的情況下,MQe有針對的錯誤恢複機制保障消息的正确傳輸。 為消息、隊列、和相關資料提供擴充的安全保護,同時包括消息的存儲和傳輸過程。 為移動裝置提供特别的支援,允許MQe随着移動裝置漫遊,并保持連接配接的穩定。 簡單的管理和操作,允許使用者在基礎操作上定制自己的規則。
MQe的基本組成
MQe最基本的幾個元素是消息、隊列、隊列管理器、連接配接、擴充卡和規則等。
MQe的消息和WMQ的消息是不同的,後者的消息是位元組流,分為消息Header和消息Body。WMQ建立消息Header,它包括應答隊列,消息ID等重要的資訊。MQe的消息沒有Header和Body之分,消息是多個MQeFields對象組成。每個MQeFields包括對象的名字,資料類型和資料。MQe支援Boolean、Integer、Unicode等多種資料類型。MQe的Java API提供一個繼承MQeFields的子類MQeMsgObject,它由多個MQeFields組成,并且提供更多的操作方法。MQe在傳輸消息之前會對消息增加一些屬性,這些屬性用來告訴遠端隊列管理器發送方的相關資訊。屬性同樣以MQeFields的方式出現,并且在消息被遠端隊列管理器接收後删除。
隊列通常是為應用程式儲存消息,每個隊列都是屬于一個隊列管理器。應用程式不允許直接通路隊列,讀寫隊列的操作通過隊列管理器來完成。MQe主要包括以下幾種隊列:
本地隊列(Local Queue):最簡單的隊列,所有的消息都存放在本地隊列中。 遠端隊列(Remote Queue):它是遠端隊列管理器中的一個本地隊列的别名。 存儲發送隊列(Store-and-forward Queue):它為一個或者多個遠端隊列管理器儲存資料。存儲發送隊列可以用push方式把消息發送到目的隊列管理器,也可以等待目的隊列管理器用pull方式讀取消息。這部分功能隻有Java語言支援。 本地服務隊列(Home-server Queue):它用pull的方式從存儲發送隊列中讀取消息。這部分同樣隻有Java語言支援。 WMQ 網橋隊列(Bridge Queue):Bridge Queue是一種特殊形式的隊列,它可以被看作為WMQ隊列管理器中一個隊列的遠端隊列。Bridge Queue對所指向的WMQ隊列讀/寫資料。它通過消息的必要轉化來保證MQe與WMQ之間消息的正确交換。Bridge Queue隻存在于網橋隊列管理器。
MQe的隊列管理器是系統的核心部分,它提供對隊列和消息的集中式管理。隊列管理器最小機關是基本隊列管理器(Basic Queue Manager),在這個基礎上加上連接配接和遠端隊列定義則被配置成用戶端隊列管理器(Client Queue Manager)。在用戶端隊列管理器上加上偵聽器(Listener)則成為服務端隊列管理器(Server Queue Manager),再在這個基礎上加上網橋功能配置成網橋隊列管理器(Bridge Queue Manager)。用MQe的程式設計接口可以建立隊列管理器,對它進行配置或者讀取已經存在的配置資訊。當隊列管理器處于active狀态後,它能夠處理收到的操作請求,完成讀寫隊列操作。
連接配接(Connection)用來關聯兩個隊列管理器,連接配接的資訊被儲存在本地隊列管理器的配置中。MQe的連接配接支援消息同步和異步的傳輸模式,并且可以對被傳輸的消息進行加密、壓縮和認證。MQe還提供Client/Server的操作,用戶端向服務端發送消息請求,服務端隊列管理器執行操作後傳回結果,這個request/response的操作過程以同步方式進行。
擴充卡(Adapter)是MQe通路裝置接口的工具。通道(Channels)利用協定擴充卡(Protocol Adapter)來把消息用TCP/IP、HTTP、UDP等協定傳輸。存儲擴充卡(Storage Adapter)是隊列管理器通路裝置檔案系統,存儲配置資訊和消息内容的接口。規則(Rule)允許讓使用者定制某些子產品的行為。MQe提供了預設的規則,在實際應用中,開發者可以根據需要靈活的定制這些規則。例如,隊列管理器處于active狀态後網橋子產品是否需要被啟動等。見圖二。
圖二 用MQe_Explorer看到的MQe基本元素
MQe Bridge功能
為了和WMQ隊列管理器中的隊列交換消息,MQe需要具備網橋(Bridge)功能。網橋子產品是Java語言實作,這些類作為一個Jar包被儲存在MQe安裝目錄下java/jars/MQeGateway.jar。
網橋允許MQe通過Client/Server通道通路WMQ隊列。一個網橋隊列管理器可以包括多個連接配接到分布式環境下WMQ的網橋。每個子網橋都包含一個指向WMQ的Proxy,由它下面的用戶端連接配接(Client Connection)元素建立與WMQ的連接配接。用戶端連接配接擁有一個偵聽器(Listener)往WMQ的傳輸隊列(Transmit Queue)中讀寫資料。偵聽器把消息從MQe網絡中寫到WMQ的傳輸隊列,并且用Pull的方法從對方的傳輸隊列中讀消息。讀到的消息最終是儲存在網橋隊列中。
因為MQe的消息和WMQ中的消息是完全不同的兩種格式。是以,在前者到後者的消息傳輸前,網橋會對消息進行轉換成WMQ的消息格式。WMQ目前不支援對MQe的消息解析,它隻能把消息儲存在本地隊列中,讓應用程式來完成解析。消息從WMQ隊列到MQe隊列時,網橋部分的消息轉換子產品會把消息轉換為MQeMsgObject對象。MQeMsgObject是多個MQeFields組成,WMQ消息會作為其中一個MQeFields對象存在。
MQe的程式設計模型
MQe主要提供兩種語言的應用程式設計接口:Java和C。
具體來說,Java語言可以細分為三大類的程式設計接口:
基于J2SE的API:提供對所有MQe功能的支援。包括消息加密認證,網橋等子產品。 基于J2ME的API:在CDC/Foundation規範支援的CVM上,MQe提供與J2SE同樣強大的API,視真實裝置的硬體條件,這些API也可以選擇性的被加載。在CLDC/MIDP規範支援的KVM上,MQe隻提供用戶端網橋管理器相關的API。 對JMS的支援:目前隻支援Point-to-Point的程式設計模型,對Pub/Sub程式設計模型不支援。
MQe對C語言的程式設計接口也可以分為下面幾類:
C綁定接口:提供與MQe在J2SE平台上類似的API。但不支援存儲發送隊列和本地服務隊列。 C本地接口:提供通路MQe大部分功能的API。但它不提供對網橋隊列管理器的支援。并且,在消息加密和傳輸擴充卡協定的支援上,都有一定的限制。它是C綁定接口的一個子集。 對Palm的C接口:針對Palm OS提供MQe部分API,隻支援用戶端隊列管理器。
3. MQe與Websphere MQ內建的原型系統
在我們應用系統中,角色A向角色B發送即時消息。角色A的消息經過伺服器端的路由,由伺服器端對消息進行格式轉換和内容處理後,再發送給角色B。這個流程涉及MQe和WMQ之間的內建。
具體來說,流程中的角色A和角色B都有一個Palm裝置,在Palm OS裡安裝了MQe,并且安裝基于MIDP的應用程式,這部分應用程式負責通路本地MQe和使用者UI的工作。一個即時消息由角色A建立并發送到MQe Server上。MQe Server被配置成具有網橋功能,能把來自Palm上MQe的消息轉發給WMQ。消息發送到WMQ的本地隊列後,服務端在對消息相應處理之後,把消息發送回MQe Server。角色B會從MQe Server上的本地隊列中讀取處理過後的消息,MIDP應用程式把通路的結果顯示在Palm裝置上。流程圖見圖三:
圖三 MQe與WMQ內建的流程圖
配置MQe Server與WMQ
MQe Server是Palm裝置上的MQe與WMQ通信的橋梁,是以它必須具備網橋的功能。我們借助MQe_Explorer來作配置工作,它是類似WMQ資料總管的可視化工具。分下面6個步驟來完成這個操作。
1. 安裝MQe和WMQ。運作MQe安裝檔案目錄下的win32/setup.exe,選擇安裝的目錄。MQe安裝完畢後,安裝MQe_Explorer。設定相應的Classpath,如果MQe的安裝路徑是C:/IBMJavasoft/MQe,MQe_Explorer的安裝路徑是C:/IBMJavasoft/MQe_Explorer,那麼在Windows的環境變量Classpath後加上C:/IBMJavasoft/MQe/Java和C:/IBMJavasoft/MQe_Explorer/MQe_ExplorerV2.jar。
2. 運作MQe_Explorer,選擇File>New>Queue Manager。輸入隊列管理器名字GateWayQM,選擇配置資訊存儲的位置,預設其他選項。見圖四。MQe的預設的擴充卡MQeDiskFieldsAdapter會把所有的配置資訊和消息寫入Windows檔案系統中。使用者也可以選擇其他擴充卡,例如MQeMemoryFieldsAdapter,它會把這些資訊寫到記憶體中。我們需要的是一個不會因為重新開機而丢失的資訊的隊列管理器,是以不能選擇這個擴充卡。擴充卡選項在Detail屬性頁的Q adapter下拉框中可以選擇。
圖四 用MQe_Explorer傳建MQe的隊列管理器
啟動這個簡單的隊列管理器有兩種方式,用MQe提供的API程式設計,或者用MQe_Explorer來打開隊列管理器配置資訊,MQe将自動啟動。通常在配置MQe的時候,我們選擇後者,但是在應用運作的情況下,用自己編寫的程式來啟動MQe更為合适。
3. 然後用MQ資料總管在WMQ中建立一個隊列管理器WBRK_QM,設定為預設隊列管理器。選擇開始>程式> IBM WebSphere MQ > WebSphere MQ資料總管,展開節點,選擇隊列管理器,右鍵建立>隊列管理器。輸入預設的傳輸隊列:TranQ。圖五:
圖五 用WMQ的資料總管中建立隊列管理器
這個向導總共有四個步驟,預設其他參數。在第四步中輸入偵聽端口1414。
4. 為隊列管理器WBRK_QM建立本地隊列、傳輸隊列和伺服器連接配接通道。
本地隊列:PubQ,PubSubSycQ。PubQ儲存來自MQe Server的消息。PubSubSycQ是GateWayQM和WMQ通信儲存同步資訊的隊列。
傳輸隊列:TranQ。在建立隊列管理器的時候,我們已經設定TranQ就是預設傳輸隊列。
遠端隊列:SubQ。該隊列指向GateWayQM上本地隊列SubQ。我們用它測試從WMQ到MQe的消息傳遞是否成功。
服務端連接配接通道:BridgeChannel。它将偵聽來自GateWayQM請求,并且建立連接配接。
要建立上述元素,可以用MQ的資料總管,也可以在指令行下完成。在Windows指令行視窗下執行:runmqsc,然後輸入下面的腳本。
DEFINE QLOCAL('PubQ') Persistent messages OK DEFINE QLOCAL('PubSubSycQ') Persistent messages OK DEFINE QLOCAL('TranQ') USAGE(XMITQ) DEFINE QREMOTE('SubQ') RNAME('SubQ') RQMNAGE('GateWayQM') XMITQ('TranQ') DEFINE CHANNEL('BridgeChannel') CHLTYPE( SVRCONN) END
5. 配置MQe Server的網橋子產品。打開MQe_Explorer,選擇File>Open,找到MQe配置資訊的檔案路徑,在這個例子中是C:/IBMJavasoft/MQe/GateWayQM.ini。選擇确定後MQe Server配置資訊會被讀取,MQe Server啟動。展開MQe root,出現一個樹狀結構,選取Bridges節點,滑鼠右鍵選擇彈出菜單中的New Bridge。在彈出的對話框中輸入網橋的名字,其他都預設不改。網橋的名字可以随意取(但并不是所有MQe元素都可以随意命名,這将在後面可以看到),這裡我們用BrokerBridge。
完成上述操作後,點選BrokerBridge這個節點,選擇彈出菜單的New MQ Proxy,輸入名字必須是WBRK_QM,它就是要連接配接的WMQ的QM名字。在Host欄裡輸入WMQ所在的機器IP位址。見圖六。
圖六 MQ Proxy的配置
選擇剛才建立的MQ proxy節點,它的名字是WBRK_QM。右鍵選擇彈出菜單中的New Client Conn。我們要為這個proxy建立一個到WMQ的連接配接,它的名字必須和WMQ的伺服器連接配接通道一緻,也就是BridgeChannel。見圖七。
圖七 Client Connection的配置資訊。
這個對話框還有一個叫Detail的頁,選擇後你會發現很多可以選擇的參數。在最簡單的情況下,我們隻需要輸入WMQ 的偵聽Port和WMQ上用于同步消息的隊列,留下其他所有參數為預設值。
選取BridgeChannel這個節點,右鍵選擇New Listener,建立一個MQe的偵聽器。它的名字必須與WMQ上WBRK_QM的預設傳輸隊列相同,也就是TranQ。我們的網橋配置基本完成,選擇建立的BrokerBridge,啟動它。如果看到Bridge run state是running則表示配置正确。
6. 網橋運作成功後,建立隊列來測試MQe與WMQ之間消息交換。WMQ的隊列管理器之間互相通信是通過發送方通道和接收方通道,而MQe與WMQ互相通信則要求建立一個到WMQ的連接配接和一個網橋隊列。具體操作是選擇Connections節點,New Connections。輸入名字必須是WMQ中的隊列管理器名字WBRK_QM。連接配接的類型選擇Alias/MQ。
然後選擇Local Queues節點,選擇彈出菜單的New Queue,建立一個網橋隊列。我們為這個隊列輸入名字:PubQ,它與WMQ的本地隊列PubQ同名。輸入隊列的Destination屬性:WBRK_QM。再選擇隊列的類型為Bridge。還有最重要的一步還沒有做,就是選擇Bridge屬性頁,輸入對應的網橋資訊。如圖八。
圖八 網橋隊列的屬性
現在我們可以通過MQe Server來向WMQ發送消息。選擇建立的網橋隊列PubQ,New Message會彈出一個消息對話框,輸入消息的内容和編碼方式等屬性,點選确定。在看到Message Sent……的資訊後,打開WMQ的資料總管,展開WBRK_QM節點,選擇隊列:PubQ,浏覽隊列的消息。如果看到消息的内容與MQe中輸入的内容一緻,表明從MQe到WMQ的消息通道已經成功建立。
我們還需要驗證WMQ同樣可以把消息發送給MQe Server。在MQe Server中建立一個本地隊列,預設所有屬性,輸入隊列名SubQ。在本章節的先前部分,我們已經用MQ腳本語言為WBRK_QM建立了指向MQe中SubQ的遠端隊列,它的名字也是SubQ。進入Windows的指令行,輸入amqsput SubQ WBRK_QM,回車後輸入消息内容:Message from WMQ,再次回車。用MQe_Explorer檢視SubQ的消息,如果看到來自WMQ的消息,表明WMQ到MQe的消息通道也已經成功建立。
到次,MQe Server的網橋功能已經配置完畢,MQe Server與WMQ的雙向消息通道也已經建立。接下來我們要把消息擴充到移動裝置上,讓移動裝置通過MQe Client,實作與MQe Server的通信,并且通過MQe Server,完成與内部系統的WMQ消息交換。
MQe Client for Palm
MQe對Palm有兩種方式支援:用C實作的MQe Client和用MIDP實作的MQe Client。在這裡我們采用基于MIDP的MQe Client,用IBM Websphere Micro Environment (WME)5.0作為J2ME的運作環境,用IBM Websphere Device Developer(WSDD)5.0作為J2ME應用的開發工具。WME的核心是IBM的J9虛拟機,和針對不同級别裝置實作的API。J9支援Palm OS、Pocket PC在内的多種嵌入式系統。WSDD是基于eclipse技術的開發工具,它與WME緊密結合,開發的程式可以直接在WME中部署和運作。WSDD對Palm裝置有着很好的支援,可以與Palm OS 3.5以上和4.X的Emulator和真實裝置內建。用MIDP編寫的程式可以通過WSDD直接在安裝了WME的Palm Emulator和真實裝置上運作和調試。WSDD還有微分析器,可以對程式占用系統資源等資訊作出詳細的分析。但是WME對Palm OS 5.0以上的裝置和Simulator都不支援。對于安裝了WME的Palm OS 4.X Emulator,MIDP中與UI相關的部分API,例如javax.microedition.lcdui.Form、javax.microedition.lcdui.List等,也不能正常的工作。
MQe并沒有一個直接可以在Palm裝置上安裝的PRC格式的應用包,也沒有類似MQe_Explorer的工具支援在Palm OS配置MQe。是以我們隻能用API方式來配置和啟動MQe。MQe安裝目錄下的Java/Jars/MQeMidp.jar,它包括MIDP環境下的MQe Client所需要的API。在WSDD中建立一個J2ME for J9,選擇建立MIDP套件項目。見圖九。在項目的特征中把MQeMIDP.jar作為外部Jar包加入。
圖九 用WSDD建立一個MIDP套件項目
建立的項目要實作兩個部分功能:MQe Client的核心部分;使用者UI相關的邏輯。前者可以參考MQe安裝目錄下的Java/examples/midp/exampleapp/messageservice下面的類,它們用MIDP API實作一個MQe Client,并且操作管理這個隊列管理器。改變這些類的包名後,把它們加入到項目中。具體分析,這些類的作用是:
MessageService:接口,它抽象了MQe基本操作,例如啟動/停止隊列管理器,建立隊列,建立連接配接,發送/讀取消息等。 MQeMessageService:用MIDP API和MQe MIDP API(MQeMIDP.jar),實作了MessageService接口。隻要得到這個類的執行個體,就可以完成對MQe的所有操作。 QueueManagerRules:在MIDP環境下,為隊列管理器定制規則。 MQeMessageServiceConstants:接口,與MQe相關的屬性常量都在這裡定義。 MQeMessageServiceParameters:實作了MQeMessageServiceConstants接口,用一組getter/setter方法提供對接口中定義的字段的通路。
值得注意的是,MIDP環境中的MQe Client和MQe Server有很多差別,例如用MQeMidpHttpAdapter作為隊列管理器間消息傳輸協定;用MQeMidpFieldsAdapter把隊列管理器配置資訊存儲到MIDP的RecordStore中。對開發人員來說,選擇messageservice目錄下的這些類就可以避免自己處理這些底層問題。在這部分代碼的基礎上,剩下的工作就是編寫邏輯代碼來确定何時啟動關閉MQe、何時發送消息,發送怎麼樣的消息内容和發送到哪個遠端隊列。
編寫邏輯相關的類時,我們将指定MQe Client的隊列管理器名字(MobileQM)、MQe Server的IP位址、隊列管理器的名字(GateWayQM)、遠端隊列的名字(TempPubQ)等。我們用MessageService接口裡面的方法來建立到GateWayQM的Connection和遠端隊列指向GateWayQM上的本地隊列TempPubQ,然後啟動MobileQM。應用程式用Midlet來實作,它是在MIDP環境中運作的小程式。我們為消息發送者A和消息接受者B分别設計對應的Midlet。角色A的SenderMidlet類在startAPP()方法中執行個體化控制隊列管理器的類(MQeMessageService),建立MobileQM,并使它處于active 狀态。在取得輸入的即時消息後,SenderMidlet調用負責發送的SenderModelClient類中的send()方法,向MQe Server發送消息。這部分的代碼如下:
public void send() { try { MQeMsgObject msg = new MQeMsgObject(); msg.putUnicode("MessageContent", strMsgContent); //發送者輸入的消息内容 msg.putInt(MQe.Msg_ExpireTime, 900000); //設定消息的失效時間 // 得到MessageService執行個體,用它把消息發到MQe Server上的目的隊列。 getMsgService().sendMessage(serverQMname, serverQname, msg); processStatus(" Message has been sent. " ); //把操作結果用SenderMidlet中的javax.microedition.TextBox元件顯示給發送者。 }catch (Exception e) { e.printStackTrace(); processStatus(" Unable to sent message, try again" ); } }
在把這部分程式部署到Palm裝置上前,我們需要把它打成PRC格式的安裝包。WSDD支援把Java類編譯成Palm裝置可以執行的代碼,并打成PRC安裝包。可以通過在wsddbuild.xml中添加一個Palm平台的建構來完成。但是WSDD 5.0的編譯器有一定的缺陷,它的優化機制常常會作出錯誤的判斷,會把一些外部Jar裡的類不放到PRC包中,進而在執行建構發生類找不到的錯誤。解決這個問題的方法是打開建構的屬性檔案,選擇包括/排除屬性,添加我們所要用到的API,強制編譯器去讀取這些類。在這個的項目中,我們指明類的包名,防止類丢失。圖十。
圖十 編輯建構的屬性資訊
消息的接受者B是一個類似的MIDP應用。它從MQe Server的隊列中取回消息,在WME環境中用MIDP的RecordStore存儲所有的即時消息,維護一個類似手機短信的消息管理子產品。同樣,角色B的ReceiverMidlet首先需要建立并激活本地的用戶端隊列管理器(MobileQM),是以它也要借助messageservice包内的類。在MobileQM成功啟動後,ReceiverMidlet啟動一個線程,從GateWayQM上的本地隊列中讀取消息。這裡用Browse,而不是Get方式讀取消息,因為角色B對應的是多個實體,他們都需要取得消息内容。角色B在取得消息後,首先與RecordStore中的消息記錄比較,判斷是否新消息,如果是才會做相應處理。
public void run() { while(true) { Vector vec = new Vector(); //得到MessageService執行個體,用browse的方式取得隊列中所有的消息 getMsgService().browseMessages(serverQMname, serverQname, null, null, 0, false, vec); //把Vector中的消息逐個與RecordStore中的消息作比較。 for(int i = 0; i < vec.size(); i++) { MQeMsgObject msg = (MQeMsgObject)vec.elementAt(i); if(!detectMsg(msg)) //判斷目前是否是新的消息。 { //是新的消息,把它放到RecordStore中存儲起來,在UI子產品中提示使用者。 RMSMsgRepository rep = new RMSMsgRepository(); ................. //存儲消息,提示接受者有新消息到來等操作。代碼省略。 }else { Thread.sleep(3000); //如果不是新的消息,等待一下。 } } } }
角色B收到的消息在Palm Emulator的顯示如圖十一:
圖十一 Palm Emulator上的消息清單
內建MQe Client、MQe Server和WMQ
到目前為止,這個流程還不能正常運作。讓我們來看看還要做哪些努力。
1. 在GateWayQM上建立一個Comms Listeners,偵聽來自Palm裝置上MobileQM的消息。這個操作相當簡單,要注意的是在選擇偵聽器的Adapter的時候一定要選擇MQeTcpipHttpAdapter。此外,它偵聽的端口與MobileQM中指定的MQe_Server_Port要相同。
2. 我們已經知道MobileQM把消息發給GateWayQM,由後者把消息發給WMQ中的WBRK_QM,再由伺服器端對消息做對應處理。問題是GateWayQM中的網橋隊列PubQ是一種特殊的遠端隊列,是以在MobileQM中我們無法建立一個指向遠端隊列的遠端隊列。這聽上去有點拗口,換個角度說,遠端隊列隻能指向另外一個隊列管理器中的本地隊列。解決的方案是在GateWayQM中建立一個臨時的本地隊列TempPubQ,MobileQM先把消息發到該隊列,然後再運作一個應用程式來從臨時的本地隊列中讀取消息,驗證消息的合法性後放到網橋隊列PubQ。
3. 消息從GateWayQM發到WBRK_QM後的流程。在我們的應用系統中,WBI Message Broker對消息做一個簡單的Pub/Sub的流程。最終,GateWayQM會以Pull的方式從WBRK_QM的SubQ中取回消息。
我們重點看一下第二個問題,它與本文的主題相關密切。在文章開始部分曾提到,在配置MQe的時候MQe_Explorer是個非常好的工具,但是在應用開發完畢要正式使用的時候,它卻不是最好的選擇。MQe_Explorer不像MQ資料總管,後者提供完整的程式設計接口來讓開發者操作内部的對象和消息。MQe_Explorer不提供任何這樣的接口,是以我們要自己建立一個項目來啟動這個已經配置完畢的隊列管理器,并且完成消息從TempPubQ到PubQ的轉移。實作這兩個部分并不複雜,建立一個普通Java項目,把MQe安裝目下的Java/examples/queuemanager類加到其中,并且在為項目添加兩個外部Jar包:MQe_ExplorerV2.jar和MQeGateway.jar。其中啟動隊列管理器的代碼如下:
public String start() { //讀取配置GateWayQM資訊,用MQeServer類來啟動它。 MQeServer gw = new MQeServer("C://IBMJavaSoft//MQe//GateWayQM.ini"); try { gw.activate(true); //沒有抛出異常,表示隊列啟動成功。 return "done"; } catch (Exception e) { System.out.println("Error: activate() failed. " + e.toString()); return "Error: Start MQ Everyplace GateWay QM failure"; } }
最後,讓我們打開WBI Message Broker,看一下這個簡單的Pub/Sub流程。消息從PubQ隊列中輸入後,首先會在Compute節點上做具體的邏輯處理。如果處理正确,消息會流轉到Trace節點,由它把消息内容寫到本地的Log檔案中。如果消息處理失敗,消息将流轉到會放到MQFailure節點所指定的隊列中。Publication節點告訴WBRK_QM的SYSTEM.BROKER.CONTROL.QUEUE根據消息的Topic把消息發送給對應的訂閱者,在我們的項目中它是SubQ。圖十二。
圖十二 一個簡單的Pub/Sub流程
4 結論
MQe和WMQ的結合,讓IBM的MQ産品家族觸及到更加廣泛的領域。本文重點介紹了MQe這個産品,和用Java開發MQe,以及MQe與WMQ內建的具體方法