Linux+上的+WebSphere+MQ+开发详细讲解.docx
《Linux+上的+WebSphere+MQ+开发详细讲解.docx》由会员分享,可在线阅读,更多相关《Linux+上的+WebSphere+MQ+开发详细讲解.docx(27页珍藏版)》请在冰豆网上搜索。
Linux+上的+WebSphere+MQ+开发详细讲解
Linux上的WebSphereMQ开发快速入门
级别:
中级
软件架构师,IBM
2009年2月05日
本文将通过用于向队列发送消息和从队列接收消息的示例应用程序说明如何在Linux上着手安装和配置WebSphereMQ,以及如何为MQ环境开发Java应用程序。
引言
本文的目标是让您轻松实现Linux®上的IBM®WebSphere®MQ入门。
由于大部分Linux服务器并没有图形用户界面,因此本文将说明如何使用命令行工具在Linux上安装和配置WebSphereMQ。
本文将说明如何使用WebSphereMQJavaAPI创建两个示例Java™应用程序:
MQSend(用于向队列发送消息)和MQGet(用于从队列接收消息)。
先决条件
∙WebSphereMQV6安装包。
∙一台或两台安装了Linux的计算机。
本文使用两台安装了SuseLinuxEnterpriseServerV9的计算机,不过也可以在一台计算机上完成所有工作。
∙Linux管理技能。
∙Java开发方面的经验将有所帮助,但并非必须的,因为我们提供了经过预编译的Java示例应用程序供下载和在命令行使用。
WebSphereMQ
WebSphereMQ提供了连接层和应用程序的可靠集成,为SOA提供了所需的基础。
WebSphereMQ的主要特色功能包括:
有保证的消息交付
基于可靠队列的消息传递,可确保消息不会丢失或重复。
基于标准的开发
使用JavaMessageService(JMS)API和MessageQueueInterface(MQI)。
端到端安全
使用安全套接字层(SecureSocketsLayer,SSL)进行身份验证、消息完整性检查和数据加密。
Web服务支持
用于保证Web服务传输和可靠性的简单对象访问协议(SimpleObjectAccessProtocol,SOAP)。
异步处理
对应用程序进行分离,以支持进行独立于时间的处理。
多平台支持
支持80种以上的配置。
有关WebSphereMQ的更多信息,请参见本文结尾的参考资料。
安装WebSphereMQ
安装WebSphereMQ的过程非常简单——直接将安装包释放到目录中即可(本文使用root主目录下的mq_install)。
可以安装RPM安装包中的所有内容,但本文仅需要这部分东西。
以下是WebSphereMQV6中包括的包和目录:
IBMJava2-SDK-1.4.2-0.0.i386.rpm
MQSeriesClient-6.0.0-0.i386.rpm
MQSeriesConfig-6.0.0-0.i386.rpm
MQSeriesFTA-6.0.0-0.i386.rpm
MQSeriesIES30-6.0.0-0.i386.rpm
MQSeriesJava-6.0.0-0.i386.rpm
MQSeriesKeyMan-6.0.0-0.i386.rpm
MQSeriesMan-6.0.0-0.i386.rpm
MQSeriesMsg_Zh_CN-6.0.0-0.i386.rpm
MQSeriesMsg_Zh_TW-6.0.0-0.i386.rpm
MQSeriesMsg_de-6.0.0-0.i386.rpm
MQSeriesMsg_es-6.0.0-0.i386.rpm
MQSeriesMsg_fr-6.0.0-0.i386.rpm
MQSeriesMsg_it-6.0.0-0.i386.rpm
MQSeriesMsg_ja-6.0.0-0.i386.rpm
MQSeriesMsg_ko-6.0.0-0.i386.rpm
MQSeriesMsg_pt-6.0.0-0.i386.rpm
MQSeriesRuntime-6.0.0-0.i386.rpm
MQSeriesSDK-6.0.0-0.i386.rpm
MQSeriesSamples-6.0.0-0.i386.rpm
MQSeriesServer-6.0.0-0.i386.rpm
MQSeriesTXClient-6.0.0-0.i386.rpm
PreReqs
READMEs
copyright
gsk7bas-7.0-3.15.i386.rpm
lap
licenses
下面是安装步骤:
1.设置Linux服务器。
本文使用主机名WMQ1和WMQ2。
WMQ1的IP地址为192.168.28.71,WMQ2的IP地址为192.168.28.72。
2.安装WebSphereMQ前,必须执行./mqlicense.sh,以阅读和接受许可证。
3.安装所需的MQ包及WebSphereMQJava和IBMJavaSDK包,以便为WebSphereMQ开发Java客户机:
wmq1:
~/mq_install#rpm-ivhIBMJava2-SDK-1.4.2-0.0.i386.rpm
wmq1:
~/mq_install#rpm-ivhMQSeriesRuntime-6.0.0-0.i386.rpm
wmq1:
~/mq_install#rpm-ivhMQSeriesServer-6.0.0-0.i386.rpm
wmq1:
~/mq_install#rpm-ivhMQSeriesJava-6.0.0-0.i386.rpm
WebSphereMQ现在已经完成安装,并有用于进行配置的名为mqm的用户和组。
缺省情况下,WebSphereMQ安装在/opt/mqm中,队列和其他配置信息位于用户mqm的主目录中。
JavaSDK安装在/opt/IBMJava2-142中,Java解释程序位于/opt/IBMJava2-142/bin中。
下一步是进行配置。
本文为两台计算机使用了具有本地和远程队列的单个队列管理器,用于测试示例应用程序。
配置WebSphereMQ
WebSphereMQ术语和定义
队列管理器
提供队列服务和API及用于管理队列的管理功能的系统管理程序。
队列
消息所发送到的命名目的地。
本地队列
位于队列管理器本地的队列。
远程队列
驻留在其他队列管理器(可能位于其他主机上)的队列。
传输队列
以远程队列为目标的临时消息队列。
通道
队列管理器之间的通信路径。
侦听器
从客户机或其他队列管理器接受网络请求。
命令服务器
验证命令并将有效命令发送到命令处理器(后者随后执行命令)。
配置过程包括以下几个步骤:
∙创建队列管理器。
∙启动队列管理器。
∙创建队列和通道。
∙启动命令服务器、侦听器和通道。
两台WebSphereMQ计算机都需要执行这些步骤。
下面的部分将仅说明如何在WMQ1上进行配置,但在WMQ2上也需要进行这些步骤。
创建并启动队列管理器
使用root登录到WMQ1,然后键入su-mqm,以更改到用户mqm。
使用以下命令为WMQ1计算机创建队列管理器:
mqm@wmq1:
~/#crtmqmWMQ1QM
使用以下命令启动队列管理器。
mqm@wmq1:
~/#strmqmWMQ1QM
创建队列和通道
使用命令行工具配置WebSphereMQ。
以下给出了WMQ1的配置脚本。
此脚本定义本地队列、远程队列、传输队列、发送方通道和接收方通道。
将以下脚本保存为WMQ1QM.conf:
DEFINEQLOCAL('WMQ1InputQ')+
REPLACE
DEFINEQLOCAL('WMQ2QMXmitQ')+
DESCR('TransmissionQueuetoWMQ2QM')+
USAGE(XMITQ)+
TRIGGER+
TRIGTYPE(FIRST)+
TRIGDPTH
(1)+
TRIGDATA('WMQ1QM.WMQ2QM')+
INITQ('SYSTEM.CHANNEL.INITQ')+
REPLACE
DEFINEQREMOTE('WMQ1OutputQ')+
XMITQ('WMQ2QMXmitQ')+
RNAME('WMQ2InputQ')+
RQMNAME('WMQ2QM')+
REPLACE
DEFINECHANNEL('WMQ1QM.WMQ2QM')CHLTYPE(SDR)+
TRPTYPE(TCP)+
CONNAME('192.168.28.72(1414)')+
XMITQ('WMQ2QMXmitQ')+
REPLACE
DEFINECHANNEL('WMQ2QM.WMQ1QM')CHLTYPE(RCVR)+
TRPTYPE(TCP)+
REPLACE
DEFINECHANNEL('SYSTEM.ADMIN.SVRCONN')CHLTYPE(SVRCONN)+
TRPTYPE(TCP)+
DESCR('')+
HBINT(300)+
MAXMSGL(4194304)+
MCAUSER('MUSR_MQADMIN')+
RCVDATA('')+
RCVEXIT('')+
SCYDATA('')+
SCYEXIT('')+
SENDDATA('')+
SENDEXIT('')+
REPLACE
上面的配置脚本可作为其他WebSphereMQ安装的模版使用。
只需要更改粗体部分的名称,即可在其他WebSphereMQ安装中设置队列和通道。
此配置脚本中包含大量条目——有关它们的更多信息,请参见WebSphereMQ信息中心。
使用以下命令创建队列和通道,以配置WebSphereMQ:
mqm@wmq1:
~/#runmqscWMQ1QMqcreate.log
runmqsc命令用于发出WebSphereMQ命令。
在本例中,这些命令从WMQ1QM.conf文件读取,而输出被定向到qcreate.log。
打开qcreate.log,验证其中不存在语法错误,全部有效命令均得到了处理。
启动服务
需要启动命令服务器、侦听器和通道,然后就可以进行示例应用程序的部署和测试工作了。
mqm@wmq1:
~/#strmqcsvWMQ1QM&
mqm@wmq1:
~/#runmqlsr-mWMQ1QM-tTCP&
验证队列管理器和侦听器在两台计算机上运行,然后启动通道:
mqm@wmq1:
~/#runmqchl-mWMQ1QM-cWMQ1QM.WMQ2QM&
mqm@wmq1:
~/#runmqchl-mWMQ1QM-cWMQ2QM.WMQ1QM&
现在已经安装了WebSphereMQ,并进行了配置,已准备好可以进行测试了。
下面一部分将给出两个基于Java的应用程序的源代码,分别用于向队列发送消息和从队列接收消息。
示例应用程序
用于将消息放入队列中(MQSend)和从队列获取消息(MQGet)的示例Java应用程序可使用前面部分中定义的队列。
这些应用程序支持String消息,旨在用于测试和作为说明如何从Java应用程序使用WebSphereMQ的示例。
可以从脚本使用应用程序,包括各种类型的应用程序。
MQSend和MQGet都从MQConnector类进行扩展,该类可提供WebSphereMQ连接、初始化WebSphereMQ、打开和关闭队列,向队列发送消息及从队列接收消息。
MQConnector
MQConnector是用于进行发送和获取操作的超类。
该类处理打开连接和发送及获取消息的工作。
将使用属性文件对其进行配置,需要在属性文件中指定主机地址、队列管理器名称和队列名称:
queue.manager=WMQ1QM
queue.manager.host=192.168.28.71
queue.name=WMQ1OutputQ
以下是MQConnector源代码:
packagemqconn;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.IOException;
importjava.util.Properties;
importcom.ibm.mq.MQC;
importcom.ibm.mq.MQEnvironment;
importcom.ibm.mq.MQException;
importcom.ibm.mq.MQGetMessageOptions;
importcom.ibm.mq.MQMessage;
importcom.ibm.mq.MQPutMessageOptions;
importcom.ibm.mq.MQQueue;
importcom.ibm.mq.MQQueueManager;
publicclassMQConnector
{
protectedStringqManager="";//definenameofqueuemanager
protectedStringqManagerHost="";
protectedStringqueuName="";//definenameofqueue
protectedMQQueuemqQueue;
protectedMQQueueManagerqMgr;
publicstaticbooleanDEBUG=true;
publicMQConnector()
{
}
publicvoidinitMq()
{
try
{
FileInputStreamfis=newFileInputStream(newFile("mqconnect.properties"));
Propertiesprops=newProperties();
props.load(fis);
fis.close();
qManager=props.getProperty("queue.manager");
qManagerHost=props.getProperty("queue.manager.host");
queuName=props.getProperty("queue.name");
//Createaconnectiontothequeuemanager
MQEnvironment.channel="SYSTEM.DEF.SVRCONN";
MQEnvironment.hostname=qManagerHost;
debug("ConnectingtoQueueManager"+qManager+"on"+qManagerHost);
qMgr=newMQQueueManager(qManager);
}
catch(Exceptione)
{
e.printStackTrace();
}
}
publicvoidopenQueue()throwsMQException
{
//Setuptheoptionsonthequeuewewishtoopen...
//Note.AllWebSphereMQOptionsareprefixedwithMQCinJava.
intopenOptions=MQC.MQOO_INPUT_AS_Q_DEF|MQC.MQOO_OUTPUT;
//Nowspecifythequeuethatwewishtoopen,
//andtheopenoptions...
debug("Openingqueue:
"+queuName);
try
{
mqQueue=qMgr.accessQueue(queuName,openOptions);
}
catch(MQExceptionmqe)
{
//checkifMQreasoncode2045
//meansthatopenedqueuisremoteanditcannotbeopenedas
//inputqueue
//trytoopenasoutputonly
if(mqe.reasonCode==2045)
{
openOptions=MQC.MQOO_OUTPUT;
mqQueue=qMgr.accessQueue(queuName,openOptions);
}
}
}
publicvoidputMessageToQueue(Stringmsg)throwsMQException
{
try
{
debug("Sendingmessage:
"+msg);
MQPutMessageOptionspmo=newMQPutMessageOptions();
MQMessagemqMsg=newMQMessage();
mqMsg.write(msg.getBytes());
//putthemessageonthequeue
mqQueue.put(mqMsg,pmo);
}
catch(IOExceptione)
{
e.printStackTrace();
}
}
publicStringgetMessageFromQueue()throwsMQException
{
try
{
MQMessagemqMsg=newMQMessage();
MQGetMessageOptionsgmo=newMQGetMessageOptions();
//Getamessagefromthequeue
mqQueue.get(mqMsg,gmo);
//Extractthemessagedata
intlen=mqMsg.getDataLength();
byte[]message=newbyte[len];
mqMsg.readFully(message,0,len);
returnnewString(message);
}
catch(MQExceptionmqe)
{
intreason=mqe.reasonCode;
if(reason==2033)//nomessages
{
returnnull;
}
else
{
throwmqe;
}
}
catch(IOExceptione)
{
e.printStackTrace();
returnnull;
}
}
publicvoidcloseQueue()throwsMQException
{
debug("ClosingqueueanddisconnectingQueueManager...");
//Closethequeue...
mqQueue.close();
//Disconnectfromthequeuemanager
qMgr.disconnect();
}
protectedbooleanhasArg(Stringarg,String[]args)
{
for(inti=0;i{
if(args[i].equals(arg))
{
returntrue;
}
}
returnfalse;
}
publicvoiddebug(Objectmsg)
{
if(DEBUG)
{
System.out.println(msg);
}
}
}
该类向其他应用程序提供WebSphereMQ功能。
还可以在自己的应用程序中将MQConnector作为其他类的超类或实用类使用。
以下方法为Java应用程序提供消息传递功能:
initMQ()
读取属性并创建队列管理器对象。
openQueue()
打开属性文件中指定的队列。
closeQueue()
关闭已打开的队列。
disconnectMq()
断开队列管理器。
putMessageToQueue(String)
将字符串消息放置到指定的队列。
getMessageFromQueue()
从指定的队列读取字符串消息。
MQSend
MQSend(如下所示)将使用MQConnector类,是用于向队列发送消息的命令行程序。
消息作为命令行参数指定,可以使用其将文件内容作为消息发送:
packagemqconn;
importjava.io.BufferedReader;
importjava.io.FileReader;
importcom.ibm.mq.MQException;
publicclassMQSendextendsMQConnector
{
publicMQSend()
{
}
publicvoidsend(String[]args)throwsMQException
{
booleanargsAreFiles=hasArg("-f",args);
initMq();
openQueue();
for(inti=0;i{
if(args[i].equals("-f"))
continue;
if(!
argsAreFiles)
{
putMessageToQueue(args[i]);
}
else
{
try
{
//sendfilecontentsasmessage
BufferedReaderbr=newBufferedReader(newFileReader(args[i]));
StringBuffermsg=