空間站

          北極心空

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

          公告

          本博客主要是在本人收集網(wǎng)上一些精彩技術(shù)文章,有時可能因疏忽轉(zhuǎn)載的時候沒有說明轉(zhuǎn)載出處和作者,如果您認(rèn)為哪篇文章侵犯了你的版權(quán),請通知本人: EMAIL:luwei-80@163.com 歡迎您光臨本博客!

          常用鏈接

          留言簿(15)

          我參與的團隊

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          隨著計算機網(wǎng)絡(luò)和分布式應(yīng)用的不斷發(fā)展,遠程消息傳遞越來越成為應(yīng)用系統(tǒng)中不可缺少的組成部分。商業(yè)消息中間件的出現(xiàn)保證了消息傳輸?shù)目煽啃裕咝屎桶踩裕瑫r也減少了系統(tǒng)的開發(fā)周期。目前應(yīng)用最多的消息中間件產(chǎn)品為IBM MQSeries。本文就針對MQ的基本操作與配置進行詳細的闡述,希望對讀者有所幫助。
          一.MQ基本操作
          MQ中有幾個很重要的組件:隊列管理器(QueueManager)、隊列(Queue)和通道(Channel)。其基本的操作方法如下:
          創(chuàng)建隊列管理器
          crtmqm –q QMgrName
          -q是指創(chuàng)建缺省的隊列管理器
          刪除隊列管理器
          dltmqm QmgrName
          啟動隊列管理器
          strmqm QmgrName
          如果是啟動默認(rèn)的隊列管理器,可以不帶其名字
          停止隊列管理器
          endmqm QmgrName 受控停止
          endmqm –i QmgrName 立即停止
          endmqm –p QmgrName 強制停止
          顯示隊列管理器
          dspmq –m QmgrName
          運行MQSeries命令
          runmqsc QmgrName
          如果是默認(rèn)隊列管理器,可以不帶其名字
          往隊列中放消息
          amqsput QName QmgrName
          如果隊列是默認(rèn)隊列管理器中的隊列,可以不帶其隊列管理器的名字
          從隊列中取出消息
          amqsget QName QmgrName
          如果隊列是默認(rèn)隊列管理器中的隊列,可以不帶其隊列管理器的名字
          啟動通道
          runmqchl –c ChlName –m QmgrName
          啟動偵聽
          runmqlsr –t TYPE –p PORT –m QMgrName
          停止偵聽
          endmqlsr -m QmgrName
          MQSeries命令
          定義死信隊列
          DEFINE QLOCAL(QNAME) DEFPSIST(YES) REPLACE
          設(shè)定隊列管理器的死信隊列
          ALTER QMGR DEADQ(QNAME)
          定義本地隊列
          DEFINE QL(QNAME) REPLACE
          定義別名隊列
          DEFINE QALIAS(QALIASNAME) TARGQ(QNAME)
          遠程隊列定義
          DEFINE QREMOTE(QRNAME) +
          RNAME(AAA) RQMNAME(QMGRNAME) +
          XMITQ(QTNAME)
          定義模型隊列
          DEFINE QMODEL(QNAME) DEFTYPE(TEMPDYN)
          定義本地傳輸隊列
          DEFINE QLOCAL(QTNAME) USAGE(XMITQ) DEFPSIST(YES) +
          INITQ(SYSTEM.CHANNEL.INITQ)+
          PROCESS(PROCESSNAME) REPLACE
          創(chuàng)建進程定義
          DEFINE PROCESS(PRONAME) +
          DESCR(‘STRING’)+
          APPLTYPE(WINDOWSNT)+
          APPLICID(’ runmqchl -c SDR_TEST -m QM_ TEST’)
          其中APPLTYPE的值可以是:CICS、UNIX、WINDOWS、WINDOWSNT等
          創(chuàng)建發(fā)送方通道
          DEFINE CHANNEL(SDRNAME) CHLTYPE(SDR)+
          CONNAME(‘100.100.100.215(1418)’) XMITQ(QTNAME) REPLACE
          其中CHLTYPE可以是:SDR、SVR、RCVR、RQSTR、CLNTCONN、SVRCONN、CLUSSDR和CLUSRCVR。
          創(chuàng)建接收方通道
          DEFINE CHANNEL(SDR_ TEST) CHLTYPE(RCVR) REPLACE
          創(chuàng)建服務(wù)器連接通道
          DEFINE CHANNEL(SVRCONNNAME) CHLTYPE(SVRCONN) REPLACE
          顯示隊列的所有屬性
          DISPLAY QUEUE(QNAME) [ALL]
          顯示隊列的所選屬性
          DISPLAY QUEUE(QNAME) DESCR GET PUT
          DISPLAY QUEUE(QNAME)MAXDEPTH CURDEPTH
          顯示隊列管理器的所有屬性
          DISPLAY QMGR [ALL]
          顯示進程定義
          DISPLAY PROCESS(PRONAME)
          更改屬性
          ALTER QMGR DESCR(‘NEW DESCRIPTION’)
          ALTER QLOCAL(QNAME) PUT(DISABLED)
          ALTER QALIAS(QNAME) TARGQ(TARGQNAME)
          刪除隊列
          DELETE QLOCAL(QNAME)
          DELETE QREMOTE(QRNAME)
          清除隊列中的所有消息
          CLEAR QLOCAL(QNAME)
          二.配置一個能夠通信的遠程連接
          以上講述了MQ的基本命令操作,但只知道這些是沒有實際意義的。MQ的最終目的是實現(xiàn)遠程通信,所以下面就以一個具體的例子來說明如何實現(xiàn)遠程連接。這個例子的目的是建立可以實現(xiàn)消息傳遞的一對MQ服務(wù)器,它們分別基于NT和UNIX平臺。
          首先在NT端建一隊列管理器
          crtmqm –q QM_NT
          啟動隊列管理器
          strmqm QM_NT
          運行MQ控制臺命令
          runmqsc QM_NT
          創(chuàng)建死信隊列
          DEFINE QL(NT.DEADQ) DEFPSIST(YES) REPLACE
          更改隊列管理器屬性,設(shè)置其死信隊列
          ALTER QMGR DEADQ(NT.DEADQ)
          創(chuàng)建進程定義
          DEFINE PROCESS(P_NT)+
          APPLTYPE(WINDOWSNT)+
          APPLICID(’ runmqchl -c SDR_NT -m QM_NT’)
          創(chuàng)建本地傳輸隊列
          DEFINE QL(QT_NT) USAGE(XMITQ) DEFPSIST(YES) +
          INITQ(SYSTEM.CHANNEL.INITQ)+
          PROCESS(P_NT) REPLACE
          創(chuàng)建遠程隊列定義,對應(yīng)于UNIX機器上的本地隊列Q_UNIX,傳輸隊列為QT_NT
          DEFINE QREMOTE(QR_NT)+
          RNAME(Q_UNIX) RQMNAME(QM_UNIX)+
          XMITQ(QT_NT)
          創(chuàng)建發(fā)送方通道,其傳輸隊列為QT_NT,遠程主機地址為10.10.10.2,偵聽端口為1414
          DEFINE CHANNEL(SDR_NT) CHLTYPE(SDR)+
          CONNAME(‘10.10.10.2(1414)’) XMITQ(QT_NT) REPLACE
          創(chuàng)建服務(wù)器連接通道
          DEFINE CHANNEL(S_NT) CHLTYPE(SVRCONN) REPLACE
          在UNIX端創(chuàng)建隊列管理器
          crtmqm –q QM_UNIX
          啟動隊列管理器
          strmqm QM_UNIX
          添加偵聽程序
          修改/etc/services文件,加入一行:
          MQSeries 1414/tcp #MQSeries channel listener
          修改/etc/inetd.conf文件,加入一行(啟動偵聽程序)
          MQSeries stream tcp nowait mqm /usr/lpp/mqm/bin/amqcrsta amqcrsta –m QM_UNIX
          運行以下命令,以使修改起作用
          refresh –s inetd
          運行MQ控制臺命令
          runmqsc QM_UNIX
          創(chuàng)建死信隊列
          DEFINE QL(UNIX.DEADQ) DEFPSIST(YES) REPLACE
          更改隊列管理器屬性,設(shè)置其死信隊列
          ALTER QMGR DEADQ(UNIX.DEADQ)
          創(chuàng)建接收方通道,其名字必須與遠程發(fā)送方相同
          DEFINE CHANNEL(SDR_NT) CHLTYPE(RCVR) REPLACE
          創(chuàng)建本地隊列
          DEFINE QL(Q_UNIX) DEFPSIST(YES) REPLACE
          創(chuàng)建服務(wù)器連接通道
          DEFINE CHANNEL(S_UNIX) CHLTYPE(SVRCONN) REPLACE
          經(jīng)過以上操作之后,遠程連接的配置工作完成。接下來需要驗證配置是否正確。
          在NT端啟動發(fā)送方通道
          runmqchl –c SDR_NT –m QM_NT 或 start chl(SDR_NT)
          從NT端發(fā)送消息到UNIX端
          amqsput QR_NT QM_NT
          在UNIX端接收消息
          /usr/mqm/samp/bin/amqsget Q_UNIX QM_UNIX
          若能收到消息,說明配置成功。
          另,在NT下一般情況下在建立隊列管理器時會自動建立偵聽器,啟動隊列管理器時則會自動啟動偵聽程序。當(dāng)然也可以手動配置偵聽程序。
          修改\winnt\system32\drivers\etc\services文件,在文件中加入一行:
          MQSeries 1414/tcp #MQSeries channel listener
          啟動偵聽程序
          runmqlsr –t tcp –p 1414 –m QM_NT
          以上說明了怎樣建立簡單的單向傳輸網(wǎng)絡(luò)。消息從NT端傳送到UNIX端。建立從UNIX端到NT端的遠程連接和以上相仿,要建立雙向的傳輸網(wǎng)絡(luò)也是同樣的道理。
          三.配置JNDI
          用JMS實現(xiàn)消息的發(fā)送和接收時,經(jīng)常會用到JNDI。因為JNDI這種方式比較靈活,對于編程也比較簡單。
          在安裝了MQSeries Client for Java之后,在\java\bin目錄下找到JMSAdmin.config文件。該文件主要用來說明Context的存儲方式及存儲地址,對應(yīng)于文件中的兩個參數(shù)INITIAL_CONTEXT_FACTORY和PROVIDER_URL。典型的JMSAdmin.config文件內(nèi)容如下:
          #INITIAL_CONTEXT_FACTORY=com.sun.jndi.ldap.LdapCtxFactory
          INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory
          #INITIAL_CONTEXT_FACTORY=com.ibm.ejs.ns.jndi.CNInitialContextFactory
          #
          #PROVIDER_URL=ldap://polaris/o=ibm,c=us
          PROVIDER_URL=file:/d:/temp
          #PROVIDER_URL=iiop://localhost/
          #
          SECURITY_AUTHENTICATION=none
          INITIAL_CONTEXT_FACTORY表示JMSAdmin Tool使用的服務(wù)提供商。當(dāng)前有三種受支持的值。com.sun.jndi.ldap.LdapCtxFactory用于LDAP,如果使用它就必須安裝一個LDAP服務(wù)器。com.sun.jndi.fscontext.RefFSContextFactory用于文件系統(tǒng)上下文,它只需要使用者提供存放上下文的文件路徑。com.ibm.ejs.ns.jndi.CNInitialContextFactory是專門為websphere提供的,它需要和websphere的CosNaming資源庫一起使用。
          PROVIDER_URL表示會話初始上下文的URL,由JMSAdmin tool實現(xiàn)的所有JNDI操作的根。它和INITIAL_CONTEXT_FACTORY一一對應(yīng)。
          ldap://hostname/contextname 用于LDAP
          file:[drive:]/pathname 用于文件系統(tǒng)上下文
          iiop://hostname[:port]/[?TargetContext=ctx] 用于訪問websphere CosNaming名稱空間
          最后還有一個參數(shù)SECURITY_AUTHENTICATION,用于說明JNDI是否把安全性憑證傳遞給了您使用的服務(wù)供應(yīng)商。只有當(dāng)使用了LDAP服務(wù)供應(yīng)商時,才使用此參數(shù)。此參數(shù)有三個值,none(匿名認(rèn)證)、simple(簡單認(rèn)證)和CRAM-MD5認(rèn)證機制。如果沒有提供有效值,缺省值為none。
          確認(rèn)配置文件之后,可以在\java\bin目錄下啟動JMSAdmin控制臺。也可以在任何目錄下用下面的命令來啟動控制臺:
          JMSAdmin –cfg MQ_JAVA_INSTALL_PATH\java\bin\JMSAdmin.config
          其中MQ_JAVA_INSTALL_PATH為MQSeries Client for Java安裝的根目錄。
          若啟動失敗,則好好檢查一下您的環(huán)境變量是否設(shè)置正確。根據(jù)我個人的經(jīng)驗,除了把com.ibm.mq.jar和com.ibm.mqjms.jar加入到環(huán)境變量外,還要把fscontext.jar和providerutil.jar加入到環(huán)境變量。
          進入JMSAdmin控制臺后,您可以自由定義sub context。對于子上下文的操作,主要有一下命令:
          display ctx
          define ctx(ctxname)
          change ctx(ctxname)
          change ctx(=up)
          change ctx(=init)
          delete ctx(ctxname)
          當(dāng)然,在這里的主要任務(wù)并非是用來定義sub context,而是用來定義以下幾個對象:
          MQQueueConnectionFactory
          MQTopicConnectionFactory
          MQQueue
          MQTopic
          (還有其它的一些對象,如MQXAQueueConnectionFactory等,不常用到,在此不作說明。)
          可以使用很多動詞來操縱目錄名稱空間中的受管理對象。ALTER、DEFINE、DISPLAY、DELETE、COPY和MOVE,它們的用法都算比較簡單,這里只列舉一二以作說明。
          例一:定義一QueueConnectionFactory,連接主機10.10.10.18,端口1414
          DEFINE QCF(EXAMPLEQCF)+
          DESC(Example Queue Connection Factory)+
          TRAN(CLIENT)+
          HOST(10.10.10.18)+
          QMGR(QM_EXAMPLE)+
          CHAN(S_EXAMPLE)+
          PORT(1414)+
          CCSID(1381)
          例二:定義一Queue,其對應(yīng)于MQ中的Q_EXAMPLE
          DEFINE Q(EXAMPLEQL)+
          DESC(Local queue)+
          QMGR(QM_EXAMPLE)+
          QUEUE(Q_EXAMPLE)+
          CCSID(1381)
          四.用JMS實現(xiàn)MQ編程
          上面我們說明了怎樣用JMSAdmin Tool定義MQ對象的上下文。我們的最終目的是要用JMS來實現(xiàn)MQ編程,以實現(xiàn)在程序中對MQ隊列進行收、發(fā)消息。所以,下面我們將重點討論一下MQ的JMS實現(xiàn)。
          如果您對JMS編程很熟悉,那么您也就會用JMS來實現(xiàn)MQ編程,因為用JMS來編寫MQ程序與編寫一般的JMS程序沒有太大的差別。舉個例子,當(dāng)我們想發(fā)送一條消息到MQ的隊列中,再從該隊列中取回消息時,我們編程時主要有四個步驟。首先我們要初始化在程序中要用到的對象,然后才可以發(fā)送消息到隊列中去,再就是收取消息了,最后要清除那些永久對象。這些都和普通的JMS程序相當(dāng)。程序的源代碼如下:
          import java.util.Hashtable;
          import javax.jms.*;
          import javax.naming.*;
          import javax.naming.directory.*;
          public class sample {
          protected QueueConnectionFactory factory=null;
          protected QueueConnection connection;
          protected QueueSession queueSession;
          protected TextMessage outMessage;
          protected QueueSender queueSender;
          protected QueueReceiver queueReceiver;
          public static final String qcfLookup="EXAMPLEQCF";
          public static final String qLookup="EXAMPLEQL";
          public static final String icf = "com.sun.jndi.fscontext.RefFSContextFactory";
          public String url ="file:/d:/temp";
          public void sampleInit() throws Exception {
          Hashtable environment = new Hashtable();
          environment.put(Context.INITIAL_CONTEXT_FACTORY, icf);
          environment.put(Context.PROVIDER_URL, url);
          environment.put(Context.REFERRAL, "throw");
          Context ctx=new InitialDirContext(environment);
          factory = (QueueConnectionFactory)ctx.lookup(qcfLookup);
          Queue q1=null;
          q1=(Queue)ctx.lookup(qLookup);
          connection = factory.createQueueConnection();
          queueSession = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
          queueSender = queueSession.createSender(q1);
          queueSender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
          outMessage = queueSession.createTextMessage();
          queueReceiver = queueSession.createReceiver(q1);
          connection.start();
          }
          public void sendMessageOut(String message) throws JMSException {
          outMessage.setText(message);
          queueSender.send(outMessage);
          }
          public String receiveMessage() throws Exception{
          return ((TextMessage)queueReceiver.receive()).getText();
          }
          public void sampleClose() throws JMSException {
          queueSession.close();
          connection.close();
          }
          public static void main(String[] args){
          String rec;
          sample sp = new sample();
          try {
          sp.sampleInit();
          sp.sendMessageOut("Hello World!");
          java.lang.Thread.sleep(4000);
          rec=sp.receiveMessage();
          System.out.println("Receive text is : "+rec);
          sp.sampleClose();
          }catch(Exception e) {
          e.printStackTrace();
          }
          }
          }
          五.遠程管理
          MQ在WINDOWS平臺下具有圖形化管理界面,但在UNIX平臺下卻只能通過命令行來進行操作。這樣就給使用者帶來很大的不便。我們都希望能通過圖形界面來進行管理配置。為了實現(xiàn)我們的想法,我們就必須建立遠程管理。
          實現(xiàn)遠程管理有以下幾個步驟:
          1.被管理隊列管理器上的命令隊列SYSTEM.ADMIN.COMMAND.QUEUE存在并可用。對于MQ 2版本應(yīng)執(zhí)行 amqscoma.tst 腳本來創(chuàng)建。
          2.使用strmqcsv命令來啟動被管理隊列管理器上的命令服務(wù)器。
          3.確定被管理隊列管理器上的服務(wù)器連接通道SYSTEM.ADMIN.SVRCONN是否存在,如果不存在則創(chuàng)建它。
          4.一般Unix、Linux平臺中MQ默認(rèn)的字符集為819,而Windows平臺為1381,所以你必須改變其字符集,使兩邊的字符集相同。一般改被管理的字符集。
          5.如果被管理隊列管理器上的操作用戶與管理隊列管理器上的操作用戶不同,那么你首先要確認(rèn)管理隊列管理器上的操作用戶在被管理隊列管理器上存在并且有管理MQ的權(quán)限,再者,你需要修改服務(wù)器連接通道SYSTEM.ADMIN.SVRCONN的MCAUSER屬性為管理隊列管理器上的操作用戶。
          6.啟動被管理隊列管理器上的偵聽器。
          做完這些工作之后,直接在管理隊列管理器的MQ管理工具中顯示被管理隊列管理器即可。然后你就可以象操作本地隊列管理器一樣,在被管理隊列管理器上定義你需要的MQ對象。
          六.通道維護
          在配置遠程連接的時候,我們曾經(jīng)創(chuàng)建過進程定義。那我們?yōu)槭裁匆?chuàng)建進程定義呢?這就涉及MQ通道維護的概念。
          通道長時間沒有消息觸發(fā)就會自動斷開連接,不再保持運行狀態(tài)。時間的長短可以由自己設(shè)定,默認(rèn)值為6000秒。消息請求再次來臨的時候,就必須再次啟動通道。有些通道,如服務(wù)器連接通道、接收方通道等是自動觸發(fā)啟動的。當(dāng)消息請求發(fā)送到通道后,通道立即啟動,進入運行狀態(tài)。但也有一些通道不會自動啟動,最典型的就是發(fā)送方通道。當(dāng)有消息請求需要使用通道進行消息傳遞的時候,發(fā)送方通道也不會自動啟動并把消息發(fā)送到遠程隊列,而是把消息留在了與其相關(guān)聯(lián)的傳輸隊列中。
          但是,在實際應(yīng)用中我們又不可能每過一段時間去啟動一次通道,或當(dāng)有消息來再去啟動通道。那應(yīng)該怎么辦?首先我們創(chuàng)建一個進程定義,這個進程定義的目的就是用來啟動發(fā)送方通道。然后我們在傳輸隊列的進程名稱屬性欄指定剛才定義的進程定義名稱,再把觸發(fā)器控制開關(guān)打開。這樣,當(dāng)有消息進入傳輸隊列后,傳輸隊列的觸發(fā)器會啟動觸發(fā)執(zhí)行指定的進程,從而啟動發(fā)送方通道,把消息傳輸?shù)竭h程隊列中去。
          七.總結(jié)
          也許你會說你已經(jīng)理解了MQ,包括基本概念、配置、管理以及程序的編寫,那么恭喜你。我也希望如此。不過MQ也許并非如此簡單,因本人水平有限,也只能到此為止,希望大家再接再厲。順便說一句,如果有什么好想法,千萬別忘了告訴我一聲。
          posted on 2007-04-27 16:14 蘆葦 閱讀(546) 評論(0)  編輯  收藏 所屬分類: IBM
          主站蜘蛛池模板: 遂川县| 金平| 日土县| 烟台市| 日喀则市| 罗山县| 昭苏县| 日照市| 牟定县| 南和县| 洮南市| 义乌市| 扶沟县| 石门县| 荔浦县| 古蔺县| 邹平县| 永兴县| 扎鲁特旗| 赞皇县| 新平| 西昌市| 辰溪县| 唐山市| 固始县| 靖江市| 定州市| 道孚县| 宜兴市| 哈密市| 枣庄市| 昭苏县| 仙游县| 肇庆市| 遵义县| 陆川县| 武穴市| 遂溪县| 甘泉县| 兴海县| 平遥县|