WebSphere MQ程序設計

    IBM 的WebSphere MQ產品可以用來方便地實現分佈式異構系統之間的消息傳遞。對於大型的分佈式系統,使用MQ進行數據通信是可以說是非常有效的,而 且適用於異構環境(如NT和多種UNIX之間通信)。本文主要介紹:MQ的核心組件介紹、MQ環境的搭建以及利用JAVA對MQ隊列管理器的操作的程序設 計,希望能起到拋磚引玉的作用。
第一部分、MQ的核心組件介紹
     MQ的核心組件包括:隊列管理器(QueueManager)、隊列(Queue)、通道(Channel)、消息(Message)和集羣(Cluster)。
隊列管理器(QueueManager)提供隊列服務,管理屬於該隊列管理器的隊列和通道等所有MQ對象。
隊列(Queue)是用於存儲消息(Message)的數據結構,有四種類型:本地隊列(LocalQueue)、遠程隊列(RemoteQueue)、別名隊列(AliasQueue)和模型隊列(ModelQueue),最常用到的是本地隊列和遠程隊列。
通道(Channel)是提供了從一個隊列管理器到其他隊列管理器的數據傳輸路徑。通道類型有若干種,其中常用的是發送方通道(SenderChannel)和接收方通道(ReceiverChannel)。
消息(Message)是應用程序之間傳遞的一系列字節數據,MQ傳遞的消息有兩部分組成:消息描述符(MessageDescriptor)和應用數據(ApplicationData)。默認最大傳遞的消息大小是4MB,可以根據需要進行設置,最大可到100MB。
集羣(Cluster)是分佈式網絡上的多個隊列管理器的集合。(本文不涉及集羣的具體內容)

第二部分、MQ環境的搭建
本文搭建的環境以Windows平臺爲例,涉及其他平臺的請讀者查閱相關文檔。
具體搭建步驟:
1、根據安裝嚮導安裝IBM WebSphere MQ v5.3軟件,安裝路徑爲:D:/IBM/WebSphere MQ。

2、 安裝成功後,請使用命令echo %classpath%檢查classpath變量中是否已經把D:/IBM/WebSphere MQ/Java/ lib下面的jar文件包含進來,如沒有包括請進行手工添加,本文要用到的2個關鍵的是:com.ibm.mq.jar和connector.jar。使 用echo %path%檢查path變量中是否已經把D:/IBM/WebSphere MQ/bin包含進來,如沒有包括請進行手工添加。

3、創建一個配置文本文件,文件名爲config.txt,內容如下(請讀者到附件下載):
* 更改QM的字符集編碼(CCSID)
     ALTER QMGR FORCE CCSID(1381)
* 定義本地隊列
     DEFINE QLOCAL('LQ_SAMPLE') REPLACE +
        USAGE(normal) +
        DEFPSIST(YES) 

4、創建一個批處理文件,文件名爲mqsetup.bat,內容如下(請讀者到附件下載):
rem 創建缺省隊列管理器,擁有100個句柄,使用線性循環日誌,容量爲 1024 × 4 K/文件,主文件10個,輔文件20個
echo Creating QM_SAMPLE 
crtmqm -t 5000 -h 100 -lc -lf 1024 -lp 10 -ls 20 -q QM_SAMPLE
rem 設置cpu個數爲1
setmqcap 1
rem 啓動隊列管理器
echo Starting Queue Manager
strmqm QM_SAMPLE
rem 從配置文件中讀入初始化命令
echo Running config 
runmqsc QM_SAMPLE < config.txt
rem 停止隊列管理器
amqmdain end QM_SAMPLE
rem 將隊列管理器設置爲自動啓動
amqmdain auto QM_SAMPLE
rem 創建隊列偵聽器,使用1414端口
amqmdain crtlsr QM_SAMPLE -t TCP -p 1414
rem 修改MQ參數,採用AdoptNewMCA方式
amqmdain reg QM_SAMPLE -c add -s Channels -v AdoptNewMCA=ALL
rem 修改MQ參數,採用KeepAlive方式
amqmdain reg QM_SAMPLE -c add -s TCP -v KeepAlive=Yes
rem 重新啓動隊列管理器
amqmdain start QM_SAMPLE

5、運行mqsetup.bat,檢查運行結果輸出是否無誤,如有錯誤,請仔細根據上述步驟進行檢查並糾錯。

6、在命令窗口中,輸入dspmq,看是否顯示如下結果:
QMNAME(QM_SAMPLE)                                    STATUS(正在運行)

7、在命令窗口中,輸入runmqsc回車,進入mq交互操作環境,輸入display queue(LQ_SAMPLE),看是否顯示如下結果:
AMQ8409: 顯示隊列細節。
    DESCR(WebSphere MQ Default Local Queue)
    PROCESS( )                               BOQNAME( )
    INITQ( )                                 TRIGDATA( )
    CLUSTER( )                               CLUSNL( )
    QUEUE(LQ_SAMPLE)                         CRDATE(2006-10-31)
    CRTIME(16.17.01)                         ALTDATE(2006-10-31)

8、輸入end退出mq交互操作環境。
自此,NT平臺上的最基本的MQ環境搭建完成了。

第三部分、利用JAVA對MQ隊列管理器的操作的程序設計
本文涉及的程序在JDK 1.4.2上測試通過。文件名爲MQSample.java,程序內容如下:
import java.io.IOException;
import com.ibm.mq.MQC;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;

public class MQSample{
     //定義隊列管理器和隊列的名稱
     private static String qmName; 
     private static String qName;
    
     public static void main(String args[]) {
         try{
             //第一個參數是隊列管理器名,第二個參數是隊列名
             qmName = args[0].trim();
             qName = args[1].trim();
         }catch(Exception e){
             System.out.println("USAGE: java MQSample 隊列管理器名 隊列名");
             System.exit(0);
         }
        
         try {
             //定義並初始化隊列管理器對象並連接 
             MQQueueManager qMgr = new MQQueueManager(qmName); 

             // 設置將要連接的隊列屬性
             // Note. All WebSphere MQ Options are prefixed with MQC in Java. 
             int openOptions = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_OUTPUT; 

             //連接隊列 
             MQQueue localQ = qMgr.accessQueue(qName, openOptions); 
            
             //定義一個簡單的消息
             MQMessage putMessage = new MQMessage(); 
             putMessage.writeUTF("Hello World!"); 

             //設置寫入消息的屬性(默認屬性)
             MQPutMessageOptions pmo = new MQPutMessageOptions(); 
            
             //將消息寫入隊列 
             localQ.put(putMessage,pmo); 
                        
             MQMessage retrievedMessage = new MQMessage();
             retrievedMessage.messageId = putMessage.messageId; 

             //設置取出消息的屬性(默認屬性)
             MQGetMessageOptions gmo = new MQGetMessageOptions(); 

             // 從隊列中取出消息
             localQ.get(retrievedMessage, gmo); 
             String msgText = retrievedMessage.readUTF();

             System.out.println("The message is: " + msgText); 

             //關閉隊列
             localQ.close(); 
             //從隊列管理器斷開 
             qMgr.disconnect(); 
         }catch (MQException ex) { 
             System.out.println("A WebSphere MQ error occurred : Completion code " 
             + ex.completionCode + " Reason code " + ex.reasonCode); 
         }catch (IOException ex) { 
             System.out.println("An error occurred whilst writing to the message buffer: " + ex); 
         }catch(Exception ex){
             ex.printStackTrace();
         }
     }
}
以 上程序接受2個輸入參數,第一個參數是隊列管理器名,第二個參數是隊列名。首先初始化MQQueueManager對象,以隊列管理器的名稱作爲參數。這 裏用的是最簡單的MQQueueManager,只能連接本機的隊列管理器。推薦使用MQQueueManager(String qmName, Hashtable hashtable)構造函數,如下:
private static Hashtable properties = new Hashtable();
properties.put("hostname", "主機名");
properties.put("port", new Integer(1414));
......
MQQueueManager qMgr = new MQQueueManager(qmName,properties); 
可以使應用程序訪問MQ服務器的特定端口。
然 後通過QueueManager的accessQueue()方法連接隊列,該方法返回MQQueue對象。然後定義了MQMessage對象,通過 writeUTF()將字符串寫入消息,進而通過MQQueue的put()方法將消息放入隊列中,然後通過get()方法取出消息,最後顯示在 console上。在程序結尾,執行MQQueue的close()方法關閉隊列,執行MQQueueManager的disconnect()斷開和隊 列管理器的連接。

對MQSample.java編譯後,輸入java MQSample QM_SAMPLE LQ_SAMPLE運行,得出如下結果:
The message is: Hello World!

在作者調試以上程序時,出現了一個錯誤:java.lang.NoClassDefFoundError: javax/resource/ResourceException
經過在IBM網站上進行搜索,說是classpath中沒有指定connector.jar文件,但是我已經在Eclipse開發環境中進行設置。
通過仔細分析,終於發現是由於JDK的緣故(我用的是WebSphere6.0裏的JDK),切換到SUN的JDK就正常了。
所以,如果你需要使用IBM的JDK的話,那麼要把MQ的這幾個包覆蓋到IBM JDK的相關路徑下。

到此,讀者應該瞭解了MQ有哪些主要的對象,環境怎麼搭建
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章