備案,以便查看
隨著計算機網絡和分布式應用的不斷發展,遠程消息傳遞越來越成為應 |
一.MQ基本操作 |
MQ中有幾個很重要的組件:隊列管理器(QueueManager |
創建隊列管理器 |
crtmqm –q QMgrName |
-q是指創建缺省的隊列管理器 |
刪除隊列管理器 |
dltmqm QmgrName |
啟動隊列管理器 |
strmqm QmgrName |
如果是啟動默認的隊列管理器,可以不帶其名字 |
停止隊列管理器 |
endmqm QmgrName 受控停止 |
endmqm –i QmgrName 立即停止 |
endmqm –p QmgrName 強制停止 |
顯示隊列管理器 |
dspmq –m QmgrName |
運行MQSeries命令 |
runmqsc QmgrName |
如果是默認隊列管理器,可以不帶其名字 |
往隊列中放消息 |
amqsput QName QmgrName |
如果隊列是默認隊列管理器中的隊列,可以不帶其隊列管理器的名字 |
從隊列中取出消息 |
amqsget QName QmgrName |
如果隊列是默認隊列管理器中的隊列,可以不帶其隊列管理器的名字 |
啟動通道 |
runmqchl –c ChlName –m QmgrName |
啟動偵聽 |
runmqlsr –t TYPE –p PORT –m QMgrName |
停止偵聽 |
endmqlsr -m QmgrName |
MQSeries命令 |
定義死信隊列 |
DEFINE QLOCAL(QNAME) DEFPSIST(YES) REPLACE |
設定隊列管理器的死信隊列 |
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 |
創建進程定義 |
DEFINE PROCESS(PRONAME) + |
DESCR(‘STRING’)+ |
APPLTYPE(WINDOWSNT)+ |
APPLICID(’ runmqchl -c SDR_TEST -m QM_ TEST’) |
其中APPLTYPE的值可以是:CICS、UNIX |
創建發送方通道 |
DEFINE CHANNEL(SDRNAME) CHLTYPE(SDR)+ |
CONNAME(‘100.100.100.215(1418) |
其中CHLTYPE可以是:SDR、SVR、RCVR |
創建接收方通道 |
DEFINE CHANNEL(SDR_ TEST) CHLTYPE(RCVR) REPLACE |
創建服務器連接通道 |
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的基本命令操作,但只知道這些是沒有實際意義的 |
首先在NT端建一隊列管理器 |
crtmqm –q QM_NT |
啟動隊列管理器 |
strmqm QM_NT |
運行MQ控制臺命令 |
runmqsc QM_NT |
創建死信隊列 |
DEFINE QL(NT.DEADQ) DEFPSIST(YES) REPLACE |
更改隊列管理器屬性,設置其死信隊列 |
ALTER QMGR DEADQ(NT.DEADQ) |
創建進程定義 |
DEFINE PROCESS(P_NT)+ |
APPLTYPE(WINDOWSNT)+ |
APPLICID(’ runmqchl -c SDR_NT -m QM_NT’) |
創建本地傳輸隊列 |
DEFINE QL(QT_NT) USAGE(XMITQ) DEFPSIST(YES) + |
INITQ(SYSTEM.CHANNEL.INITQ)+ |
PROCESS(P_NT) REPLACE |
創建遠程隊列定義,對應于UNIX機器上的本地隊列Q_UNIX |
DEFINE QREMOTE(QR_NT)+ |
RNAME(Q_UNIX) RQMNAME(QM_UNIX)+ |
XMITQ(QT_NT) |
創建發送方通道,其傳輸隊列為QT_NT,遠程主機地址為10 |
DEFINE CHANNEL(SDR_NT) CHLTYPE(SDR)+ |
CONNAME(‘10.10.10.2(1414)’) XMITQ(QT_NT) REPLACE |
創建服務器連接通道 |
DEFINE CHANNEL(S_NT) CHLTYPE(SVRCONN) REPLACE |
在UNIX端創建隊列管理器 |
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 |
創建死信隊列 |
DEFINE QL(UNIX.DEADQ) DEFPSIST(YES) REPLACE |
更改隊列管理器屬性,設置其死信隊列 |
ALTER QMGR DEADQ(UNIX.DEADQ) |
創建接收方通道,其名字必須與遠程發送方相同 |
DEFINE CHANNEL(SDR_NT) CHLTYPE(RCVR) REPLACE |
創建本地隊列 |
DEFINE QL(Q_UNIX) DEFPSIST(YES) REPLACE |
創建服務器連接通道 |
DEFINE CHANNEL(S_UNIX) CHLTYPE(SVRCONN) REPLACE |
經過以上操作之后,遠程連接的配置工作完成。接下來需要驗證配置是 |
在NT端啟動發送方通道 |
runmqchl –c SDR_NT –m QM_NT 或 start chl(SDR_NT) |
從NT端發送消息到UNIX端 |
amqsput QR_NT QM_NT |
在UNIX端接收消息 |
/usr/mqm/samp/bin/amqsget Q_UNIX QM_UNIX |
若能收到消息,說明配置成功。 |
另,在NT下一般情況下在建立隊列管理器時會自動建立偵聽器 |
修改\winnt\system32\drivers\etc |
MQSeries 1414/tcp #MQSeries channel listener |
啟動偵聽程序 |
runmqlsr –t tcp –p 1414 –m QM_NT |
以上說明了怎樣建立簡單的單向傳輸網絡。消息從NT端傳送到UNI |
三.配置JNDI |
用JMS實現消息的發送和接收時,經常會用到JNDI |
在安裝了MQSeries Client for Java之后,在\java\bin目錄下找到JMSAdmin |
#INITIAL_CONTEXT_FACTORY=com.sun.jndi.ldap.LdapCtxFactor |
INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSCon |
#INITIAL_CONTEXT_FACTORY=com.ibm.ejs.ns.jndi.CNInitialCo |
# |
#PROVIDER_URL=ldap://polaris/o |
PROVIDER_URL=file:/d:/temp |
#PROVIDER_URL=iiop://localhost/ |
# |
SECURITY_AUTHENTICATION=none |
INITIAL_CONTEXT_FACTORY表示JMSAdm |
PROVIDER_URL表示會話初始上下文的URL |
ldap://hostname/contextname 用于LDAP |
file:[drive:]/pathname 用于文件系統上下文 |
iiop://hostname[:port]/[ |
最后還有一個參數SECURITY_AUTHENTICATION |
確認配置文件之后,可以在\java\bin目錄下啟動JMSAd |
JMSAdmin –cfg MQ_JAVA_INSTALL_PATH\java\bin |
其中MQ_JAVA_INSTALL_PATH為MQSeries Client for Java安裝的根目錄。 |
若啟動失敗,則好好檢查一下您的環境變量是否設置正確 |
進入JMSAdmin控制臺后,您可以自由定義sub context。對于子上下文的操作,主要有一下命令: |
display ctx |
define ctx(ctxname) |
change ctx(ctxname) |
change ctx(=up) |
change ctx(=init) |
delete ctx(ctxname) |
當然,在這里的主要任務并非是用來定義sub context,而是用來定義以下幾個對象: |
MQQueueConnectionFactory |
MQTopicConnectionFactory |
MQQueue |
MQTopic |
(還有其它的一些對象,如MQXAQueueConnection |
可以使用很多動詞來操縱目錄名稱空間中的受管理對象。ALTER |
例一:定義一QueueConnectionFactory |
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,其對應于MQ中的Q_EXAMPLE |
DEFINE Q(EXAMPLEQL)+ |
DESC(Local queue)+ |
QMGR(QM_EXAMPLE)+ |
QUEUE(Q_EXAMPLE)+ |
CCSID(1381) |
四.用JMS實現MQ編程 |
上面我們說明了怎樣用JMSAdmin Tool定義MQ對象的上下文。我們的最終目的是要用JMS來實現 |
如果您對JMS編程很熟悉,那么您也就會用JMS來實現MQ編程 |
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.RefFSCon |
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 |
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 |
} |
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平臺 |
實現遠程管理有以下幾個步驟: |
1.被管理隊列管理器上的命令隊列SYSTEM.ADMIN |
2.使用strmqcsv命令來啟動被管理隊列管理器上的命令服務 |
3.確定被管理隊列管理器上的服務器連接通道SYSTEM |
4.一般Unix、Linux平臺中MQ默認的字符集為819 |
5.如果被管理隊列管理器上的操作用戶與管理隊列管理器上的操作用 |
6.啟動被管理隊列管理器上的偵聽器。 |
做完這些工作之后,直接在管理隊列管理器的MQ管理工具中顯示被管 |
六.通道維護 |
在配置遠程連接的時候,我們曾經創建過進程定義。那我們為什么要去 |
通道長時間沒有消息觸發就會自動斷開連接,不再保持運行狀態 |
但是,在實際應用中我們又不可能每過一段時間去啟動一次通道 |
七.總結 |
也許你會說你已經理解了MQ,包括基本概念、配置 |