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有哪些主要的对象,环境怎么搭建(请仔细研究config.txt和mqsetup.bat文件),以及如何对mq的对象进行操作。
如果读者对以上的内容有任何疑问,可以和我联系,qianh@cntmi.com
闽公网安备 35060202000074号