WebSphere
MQ(以下簡稱
MQ)是IBM公司享有盛譽的商業通信中間件。它被世界范圍的許多大型企業廣泛采用。它提供一個具有工業標準、安全、可靠的消息傳輸系統。
MQ基本由一個消息傳輸系統和一個應用程序接口組成。應用程序使用
MQ的API(消息隊列接口
MQI)函數和隊列管理器(
MQ運行時刻的程序)進行通信。隊列管理器在工作時,它需要用到對象如隊列和通道。同時,隊列管理器也是一個對象。圖1所示為
MQ應用程序在運行時刻的圖示。
 圖1 運行時刻的 MQ1 |
消息是一個信息單元,它由兩部分組成:從一個程序發往另外一個程序的應用程序數據以及消息描述符或者消息頭。
消息描述符用來標識消息(message ID),同時它還包括一些控制信息,如消息類型,消息過期的時間,消息優先級等等。
一條消息的最大長度為100MB,默認的最大消息長度為4MB。消息的最大長度依賴于
MQ的版本。
MQ第五版支持消息的最大長度為100MB。
隊列是一個安全的存儲消息的地方,消息的存儲一般是有順序的。因為消息存放在隊列中,所以應用程序可以以不同的速度、在不同的時間、不同的地點相互獨立的運行。
消息隊列通信是應用程序之間進行通信的一種方式。應用程序在沒有專有連接或者物理連接的情況下,能夠通過向隊列寫入或讀出消息進行通信,也即程序之間不是通過互相調用,而是通過向隊列發送數據來進行通信。在這種通信方式下,應用程序不需要具有并發性。對于異步的消息通信,程序發送方不需要專門等待已發消息的回復,而是可以處理下一個事件。與之相對的是,同步消息通信在處理下一個事件之前必須等待已發消息的回復。對于用戶來說,底層的協議是透明的。用戶只需要考慮會話的程序或數據入口。
MQ應用于客戶機/服務器模式或者分布式系統。應用程序可以工作在一個工作站上,也可以運行在不同平臺的不同機器上。應用程序具有很好的移植性,能夠輕松的從一個系統或者平臺轉移到另一個系統或者平臺。程序的編寫支持多種語言,包括Java。同樣的,隊列也適合許多不同的平臺。
因為MQ通過隊列進行通信,所以它可以被看成是使用間接的程序--程序方式通信。程序員可以不指定接收消息的目標程序的名稱,但是可以指定接收消息的隊列的名稱,每一個隊列和一個程序相聯系,一個程序可以有一個或者多個接收隊列,而且可以有多個輸出隊列。輸出隊列包含著很多信息,這些信息可以是用來供服務器處理的,也可以是返還給發送消息的客戶端的回復信息。
使用MQ進行通信時程序員不必擔心目標程序是否可用或是否繁忙,甚至不用考慮目標機器是否正常運行或者是否連接上了。程序員發送消息給目標隊列,而目標隊列是和目標程序相聯系的,目標程序可能目前不可用。不用擔心,MQ能夠解決這種情況,如果需要,它甚至能夠啟動目標程序。
如果目標程序不可用,消息會停留在隊列中,稍后再被處理。隊列可以在發送消息的機器中,也可以在接收消息的機器中,這取決于兩臺機器的兩個系統之間是否能夠建立連接。應用程序可以整天運行,也可以采用激發機制,所謂激發,就是指當有一條或數條消息到達隊列時自動啟動某個程序。
 圖2 消息和隊列1 |
圖2說明了兩個應用程序A和B之間是如何進行通信的??梢钥吹接袃蓚€隊列,各隊列里面存放著要接收或者發送的消息。
程序和隊列之間的方形圖表示
MQI(消息隊列接口API)。程序就是使用
MQI來和
MQ的實時程序--隊列管理器進行通信的。
簡單地說:
MQ的核心部分是一個能夠存儲消息的服務器及一組能夠轉發消息的進程,分布在多個系統(異地、異種平臺)上的應用程序依靠這種機制來交換要處理的數據2。隊列管理器作為一個服務器,把消息以可靠的方式存儲,即使機器發生故障重新啟動后依然不會丟失,其可靠級別與數據庫服務器相等。隊列管理器間通過特別的交換機制保證數據不會因為底層網絡的故障而丟失,并且能夠在多點間接力式地傳送。
JMS是J2EE中的一個接口標準,為JAVA程序定義了一種標準的使用消息交換數據的編程方式,但JMS本身并不能實現消息的傳送,一個調用JMS的應用程序發出消息調用后,具體的消息傳送工作還需要底層的消息中間件來執行傳送工作。JMS的作用就是使應用程序開發人員不需要關心底層的傳送軟件的種類,同一段程序,既可以用
MQ傳送,也可以用其他消息中間件來傳送,如WEBLOGIC內含的具有消息中間件功能的部件。
MQ軟件提供一個JAVA軟件包,里面有JMS類庫,和一套MQ的類庫。不熟悉MQI編程方法的程序員可以用JMS,比較熟悉MQI編程方法的程序則可以用MQ類庫來編程。下面的小程序是使用Java實現從隊列管理器QM_SERVER中的隊列INITQ寫入或讀出消息。
package transfer; import com.ibm.mq.*; public class SendMSG1 { private MQQueueManager qMgr;//定義一個隊列管理器變量 public static void main(String args[]) { new SendMSG1(); } public SendMSG1() { MQEnvironment.hostname="192.168.1.18";//本地IP MQEnvironment.channel="CHANNEL1";//用來通信的通道 MQEnvironment.CCSID =1381; try{ qMgr=new MQQueueManager("QM_SERVER");//隊列管理器名稱 int openOptions=MQC.MQOO_INPUT_AS_Q_DEF|MQC.MQOO_OUTPUT|MQC.MQOO_INQUIRE; MQQueue queue=qMgr.accessQueue("INITQ",openOptions,null,null,null); //建立連接 MQMessage hello=new MQMessage();//要寫入隊列的消息 try{ hello.format=MQC.MQFMT_STRING ; hello.characterSet=1381 ; hello.writeString("這是測試!"); } catch(java.io.IOException ex) {}finally{}; MQPutMessageOptions pmo=new MQPutMessageOptions(); for (int i=1;i<=5;i++)//將消息依次寫入隊列 { hello.expiry=-1; //設置消息用不過期 queue.put(hello);//將消息放入隊列 } queue.close() ;//關閉隊列 qMgr.disconnect() ; //斷開連接 } catch(Exception ex) {} finally{}; } } |
程序的運行結果如下圖3所示:
 圖3 程序運行結果界面 |
這個例子僅僅是向隊列INITQ寫入了5條相同的消息,當然,在實際應用中,消息可能是多種多樣的,如果要傳送數據庫的內容,則可以在寫入消息時,用一些特殊的符號來將各字段的數據區分開,那么在消息讀出時,也可以根據此特殊的符號來讀取數據。依據同樣的步驟:和隊列管理器建立連接-從隊列讀取消息---關閉隊列---斷開連接,可以用Java寫出如何從隊列中讀出消息。
MQ有許多顯著的優點,比如借住在不同的平臺上使用相同的應用程序接口,它能輕松的實現跨平臺通信,從而能夠使開發人員避開網絡的復雜性;比如它對消息的處理不依賴于時間,在消息創建和發送時,不受時間的限制,增加了處理的靈活性......
總之,
MQ的特點以及IBM公司在企業應用領域所付出的巨大努力,使得它具有極強的生命力?,F在,大量的政府部門、金融、電信和企業用戶使用
WebSphereMQ作為企業電子商務的基礎平臺。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=836145