IBM WebSphere MQ的簡介與實作

作者/賴學誠



前言 系統整合專案最需要的就是各個介面與平台的溝通與連結。有些需要及時回應,有些則需要確保資訊不遺漏。其中資訊不遺漏這點若是使用socket通訊等等的方式則不能確保。這時候就必須使用訊息佇列(Message Queue以下皆稱MQ)來通訊防止斷線時資料遺失或漏傳。 MQ技術是交換資訊的一種技術。可駐留在記憶體或硬碟上,佇列儲存訊息直到它們被應用程式讀走。通過訊息佇列,應用程式可獨立地執行,它們不需要知道彼此的位置、或在繼續執行前不需要等待接收程式接收此訊息。

《圖一》
MQ本身是非同步的,它允許接收者在訊息發送很長時間後再取回訊息,這和大多數通訊協議是不同的。例如WWW中使用的HTTP協議是同步的,因為客戶端在發出請求後必須等待伺服器回應。然而,很多情況下我們需要非同步的通訊協議。比如,一個程式通知另一個程式發生了一個事件,但不需要等待回應。但MQ的非同步特點,也造成了一個缺點,就是接收者必須Polling MQ,才能收到最近的訊息。 在Windows上面只要透過MSMQ就可以使用訊息佇列的技術來達到非同步的通訊。但是若溝通的程式或Server是大型主機或是JAVA平台,例如Tandem主機或J2EE環境就必須透過WebSphere MQ。 WebSphere MQ基本概念 一、佇列管理程式 控管 WebSphere MQ 佇列的每一部電腦都需要佇列管理程式。每一個佇列管理程式都有唯一的名稱。使用 WebSphere MQ 的應用程式會先連接到佇列管理程式。如果應用程式在佇列管理程式的本端位置,就可以直接連接。 沒有本端佇列管理程式的應用程式可以使用 WebSphere MQ Client,其會使用 MQI 通道來連接遠端佇列管理程式。

《圖二》
二、訊息 在WebSphere MQ中,我們把應用程序交由MQ傳輸的數據定義為訊息,我們可以定義訊息的內容。如下圖所示:

《圖三》
當應用程式使用 WebSphere MQ 傳送資料時,其會建構一則含有訊息標頭和資料的訊息。訊息標頭含有控制資訊,如:唯一的訊息 ID 和訊息格式(例如:String)。訊息標頭中也會設定訊息持續性。訊息分為兩種類型,非持續性(non-persistent)訊息和持續性(persistent)訊息,非持續性訊息是儲存在記憶體中的,它是為了提高性能而設計的,當系統掉電或MQ佇列管理器重新啟動時,將不可恢復。當使用者對訊息的可靠性要求不高,而著重系統的性能表現時,可以採用該種類型的訊息,如:當發布股票資訊時,由於股票資訊是不斷更新的,我們可能每幾秒就會發布一次,新的訊息會不斷覆蓋舊的訊息。持續性訊息是儲存在硬碟上,並且紀錄數據日誌的,它具有高可靠性,在網路和系統發生故障等情況下都能確保訊息不會消失。持續訊息會寫入磁碟中,如果系統失敗可以回復。非持續訊息不會儲存到硬碟中,因此遞送的速度較快。 三、佇列 佇列是指用來儲存訊息,直到應用程式接收它們為止的位置。如下圖所示Q1即為佇列。

《圖四》
每一個本端佇列都有名稱。應用程式可以指定這個名稱,來將訊息放到佇列中。這種傳訊形式(訊息會分送至指定的佇列)稱為「點對點」傳訊。 應用程式也會在需要時,利用佇列名稱來取得訊息。

《圖五》
WebSphere MQ能夠在各種網路條件下保證訊息的可靠傳遞,可以克服網路線路質量差或不穩定的情況,在傳輸過程中,如果通訊線路出現故障或遠端的主機發生故障,本端的應用程序都不會受到影響,可以繼續發送數據,而無需等待網路故障恢復或遠端主機正常後再重新執行。 在WebSphere MQ中,佇列分為很多種類型,其中包括:本端佇列、遠程佇列、模板佇列、動態佇列、別名佇列等。本端佇列又分為普通本端佇列和傳輸佇列,普通本端佇列是應用程序通過API對其進行讀寫操作的佇列;傳輸佇列可以想像為儲存-轉發佇列,比如:我們將某個訊息交?WebSphere MQ系統發送到遠程主機,而此時網路發生故障,WebSphere MQ將把訊息放在傳輸佇列中暫存,當網路恢復時,再發往遠端目的地。遠程佇列是目的佇列在本端的定義,它類似一個地址指針,指向遠端主機上的某個目的佇列,它僅僅是個定義,不真正佔用硬碟儲存空間。 四、通道 通道是MQ系統中佇列管理器之間傳遞訊息的管道,它是建立在物理的網路連接之上的一個邏輯概念,也是MQ產品的精華。在 MQ中,主要有三大類通道類型,即訊息通道,MQI通道和Cluster通道。 訊息通道是用於在MQ的服務器和服務器之間傳輸訊息的,需要強調指出的是, 該通道是單向的,它又有傳送(sender), 接收(receive), 請求者(requestor), 服務者(server)等不同類型,供使用者在不同情況下使用。如果要雙向傳送訊息,您必須為每一個方向定義一個通道。 MQI通道是MQ Client和MQ Server之間通訊和傳輸訊息用的,與訊息通道不同,它的傳輸是雙向的。群集(Cluster)通道是位於同一個MQ 群集內部的佇列管理器之間通訊使用的。 MQ工作原理: 首先來看本端通訊的情況,應用程序A和應用程序B執行於同一系統,它們之間可以借助訊息佇列技術進行彼此的通訊:應用程序A向佇列A1發送一條訊息,而當應用程序B需要時就可以得到該訊息。

《圖六》
其次是遠程通訊的情況,如果訊息傳輸的目標改為在系統B上的應用程序C,這種變化不會對應用程序A產生影響,用戶端程序向佇列Q1發送一條訊息,系統A的MQ 發現Q1所指向的目的佇列實際上位於系統B,它將訊息放到本端的一個傳輸佇列(Transmission Queue)。我們建立一條從系統A到系統B的訊息通道,訊息通道代理將從傳輸佇列中讀取訊息,並傳遞適條訊息到系統B,然後等待確認。只有MQ接到系統 B成功收到訊息的確認之後,它才從傳輸佇列中真正將該訊息刪除。如果通訊線路不通,或系統B不在執行,訊息會留在傳輸佇列中,直到被成功地傳送到目的地。 這是MQ最基本而最重要的技術--確保訊息傳輸,並且是一次且僅一次(once-and-only-once)的傳遞。

《圖七》
MQ提供了用於鬆耦合的連接方法,因為共享訊息的應用不需要知道彼此物理位置(網路位址);不需要知道彼此間怎樣建立通訊;不需要同時處於執行狀態;不需要在同樣的操作系統或網路環境下執行。 應用實例Demo 透過WebSphere MQ 使用者介面設定MQ: 實作一個從本端程式傳送訊息然後遠端主機回傳回應訊息的案例。 一、新增佇列管理程式 在本端IBM WebSphere MQ找到佇列管理程式,按右鍵新建。命名為QM_A。 另在遠端IBM WebSphere MQ找到佇列管理程式,按右鍵新建。命名為QM_B。

《圖八》
二、設定佇列: 在本端佇列管理程式QM_A找到佇列選項,按右鍵新建。設定傳輸佇列(A_Sender),本端佇列(QMB_Response),遠端佇列(QMA_Request)。 在遠端佇列管理程式QM_B找到佇列選項,按右鍵新建。設定傳輸佇列(B_Sender),本端佇列(QMA_Request),遠端佇列(QMB_Respose)。

《圖九》
三、定通道: 在本端佇列管理程式QM_A找到進階->通道,按右鍵新建。設定傳送端通道(Chl_AToB),與接收端通道(Chl_BToA)。 同樣的在遠端佇列管理程式QM_B找到進階->通道,按右鍵新建。設定傳送端通道(Chl_BToA),與接收端通道(Chl_AToB)。

《圖十》
四、放置測試訊息確認連線 於遠端佇列QMA_Request上按右鍵->放置測試訊息

《圖十一》

《圖十二》
於遠端QMA_Request上按右鍵->瀏覽訊息

《圖十三》
確定收到訊息,表示架設的連線正確無誤。則可以開始著手透過程式去存取。 撰寫WebSphere MQ遠端發送訊息的應用程式: 要於專案中使用WebSphere MQ的類別首先需要先安裝WebSphere MQ Server或Client,然後在專案中參考amqmdnet.dll。

《圖十四》
於程式中引入using IBM.WMQ就可以開始撰寫程式,下面貼上Demo的程式碼

《圖十五》
程式執行畫面如下,需要填寫以下資訊來連接與測試。

《圖十六》
訊息資料成功的送到QM_B上面的QMA_Request的佇列中。

《圖十七》
結語 筆者目前專案中使用到WebSphere MQ的時機是專案設計的閘道器需要同時連接外部大型主機,與內部的服務程式。因此需要使用到WebSphere MQ與MSMQ,做法是與外部主機系統透過WebSphere MQ來溝通。收到訊息後則透過MSMQ發送訊息給Server內部的Service執行。 金融交易系統在傳送交易電文時都與使用者的金錢有著重要的影響。因此不只是效率要好,資料正確性與可靠性更是重中之重。相信沒有人願意在銀行存款後卻發現沒入帳吧。透過WebSphere MQ與MSMQ的架構設計,有效提高了整個系統的傳送資料可靠性,若有發生斷線與傳輸問題甚至程式有Bug,也因為MQ的持續性訊息的特性,可以確保交易電文的原始狀態,除了可以確保使用者的金錢,若是有Bug的存在也可以方便使用原始電文來除錯。避免了交易資料憑空消失造成的後續麻煩問題。 參考資料 IBM WebSphere MQ - SupportPacs by Product: http://www-01.ibm.com/support/docview.wss?uid=swg27007197&wv=1 IBM Redbooks - WebSphere MQ Solutions in a Microsoft .NET Environment http://www.redbooks.ibm.com/ MicroSoft MSDN http://msdn.microsoft.com/en-us/library/ms711472(VS.85).aspx