1. 概述
IBM Websphere MQ Everyplace(MQe)是Websphere MQ(WMQ)产品家族系列中的一员。它是为轻量级的设备而设计,例如电话、PDA、Palm和膝上型电脑等。本文将描述一个用MQe与WMQ集成移动设备和企业内部系统的例子。
通过本文您将了解:
MQe基本概念和设计开发入门知识。 如何配置MQe Server和WMQ,使它们能够通过网桥模块互相通信。 如何开发MIDP环境下的MQe Client和应用程序。 最后,集成基于MIDP的MQe Client,MQe Server和WMQ。您需要下面的软件:
Windows 2000 Server (English) Websphere MQ Everyplace 2.0 Websphere MQ 5.3 for Windows Websphere Studio Device Developer 5.0 Websphere Business Integration Message Broker 5.02. MQe 简介
MQe在Websphere MQ产品系列中的地位
IBM Websphere MQ产品家族可以分为三大类:(见图一)
Websphere MQ Workflow:通过自动化的流程处理,简化企业内部的应用集成。目前产品是Websphere MQ Workflow 3.4。 Websphere MQ Integrator:功能强大的消息代理软件,提供实时,基于规则的智能化消息路由,消息格式转化等功能。目前产品是WBI Message Broker 5.0和WBI Event Broker 5.0。 Websphere MQ Messaging:用可靠的消息传递机制,为大型服务器和PC提供点对点连接,支持35种平台。目前产品是Webspher MQ 5.3和Websphere MQ Everyplace 2.0。图一Websphere MQ产品家族
MQ Workflow和MQ Integrator产品都是运行在MQ Messaging产品的基础上。消息传递是基于队列(Queue)和队列管理器(Queue Manager)。队列管理器管理所有的队列,以及保存在队列内部的消息。应用程序连接队列管理器(Local Queue Manager)来读写消息。如果要放一个消息到远程的队列(Remote Queue),消息是通过通道(Channel)传输到远程的队列管理器(Remote Queue Manager)。MQe和WMQ都是用类似的消息机制来传递消息。
MQe 扩展了WMQ的消息传递领域,它主要有下列几个特点:
MQe不但支持手机,PDA等低端产品和移动设备,还支持PC,服务器和大型工作站。MQe可以在Palm OS、PocketPC、Windows、Linux、Unix、AIX等环境下运行,总共支持35种操作系统。 提供轻量级的消息传递机制。在网络不稳定,带宽限制的情况下,MQe有针对的错误恢复机制保障消息的正确传输。 为消息、队列、和相关数据提供扩展的安全保护,同时包括消息的存储和传输过程。 为移动设备提供特别的支持,允许MQe随着移动设备漫游,并保持连接的稳定。 简单的管理和操作,允许用户在基础操作上定制自己的规则。MQe的基本组成
MQe最基本的几个元素是消息、队列、队列管理器、连接、适配器和规则等。
MQe的消息和WMQ的消息是不同的,后者的消息是字节流,分为消息Header和消息Body。WMQ创建消息Header,它包括应答队列,消息ID等重要的信息。MQe的消息没有Header和Body之分,消息是多个MQeFields对象组成。每个MQeFields包括对象的名字,数据类型和数据。MQe支持Boolean、Integer、Unicode等多种数据类型。MQe的Java API提供一个继承MQeFields的子类MQeMsgObject,它由多个MQeFields组成,并且提供更多的操作方法。MQe在传输消息之前会对消息增加一些属性,这些属性用来告诉远程队列管理器发送方的相关信息。属性同样以MQeFields的方式出现,并且在消息被远程队列管理器接收后删除。
队列通常是为应用程序保存消息,每个队列都是属于一个队列管理器。应用程序不允许直接访问队列,读写队列的操作通过队列管理器来完成。MQe主要包括以下几种队列:
本地队列(Local Queue):最简单的队列,所有的消息都存放在本地队列中。 远程队列(Remote Queue):它是远程队列管理器中的一个本地队列的别名。 存储发送队列(Store-and-forward Queue):它为一个或者多个远程队列管理器保存数据。存储发送队列可以用push方式把消息发送到目的队列管理器,也可以等待目的队列管理器用pull方式读取消息。这部分功能只有Java语言支持。 本地服务队列(Home-server Queue):它用pull的方式从存储发送队列中读取消息。这部分同样只有Java语言支持。 WMQ 网桥队列(Bridge Queue):Bridge Queue是一种特殊形式的队列,它可以被看作为WMQ队列管理器中一个队列的远程队列。Bridge Queue对所指向的WMQ队列读/写数据。它通过消息的必要转化来保证MQe与WMQ之间消息的正确交换。Bridge Queue只存在于网桥队列管理器。MQe的队列管理器是系统的核心部分,它提供对队列和消息的集中式管理。队列管理器最小单位是基本队列管理器(Basic Queue Manager),在这个基础上加上连接和远程队列定义则被配置成客户端队列管理器(Client Queue Manager)。在客户端队列管理器上加上侦听器(Listener)则成为服务端队列管理器(Server Queue Manager),再在这个基础上加上网桥功能配置成网桥队列管理器(Bridge Queue Manager)。用MQe的编程接口可以创建队列管理器,对它进行配置或者读取已经存在的配置信息。当队列管理器处于active状态后,它能够处理收到的操作请求,完成读写队列操作。
连接(Connection)用来关联两个队列管理器,连接的信息被保存在本地队列管理器的配置中。MQe的连接支持消息同步和异步的传输模式,并且可以对被传输的消息进行加密、压缩和认证。MQe还提供Client/Server的操作,客户端向服务端发送消息请求,服务端队列管理器执行操作后返回结果,这个request/response的操作过程以同步方式进行。
适配器(Adapter)是MQe访问设备接口的工具。通道(Channels)利用协议适配器(Protocol Adapter)来把消息用TCP/IP、HTTP、UDP等协议传输。存储适配器(Storage Adapter)是队列管理器访问设备文件系统,存储配置信息和消息内容的接口。规则(Rule)允许让用户定制某些模块的行为。MQe提供了缺省的规则,在实际应用中,开发者可以根据需要灵活的定制这些规则。例如,队列管理器处于active状态后网桥模块是否需要被启动等。见图二。
图二 用MQe_Explorer看到的MQe基本元素
MQe Bridge功能
为了和WMQ队列管理器中的队列交换消息,MQe需要具备网桥(Bridge)功能。网桥模块是Java语言实现,这些类作为一个Jar包被保存在MQe安装目录下java/jars/MQeGateway.jar。
网桥允许MQe通过Client/Server通道访问WMQ队列。一个网桥队列管理器可以包括多个连接到分布式环境下WMQ的网桥。每个子网桥都包含一个指向WMQ的Proxy,由它下面的客户端连接(Client Connection)元素建立与WMQ的连接。客户端连接拥有一个侦听器(Listener)往WMQ的传输队列(Transmit Queue)中读写数据。侦听器把消息从MQe网络中写到WMQ的传输队列,并且用Pull的方法从对方的传输队列中读消息。读到的消息最终是保存在网桥队列中。
因为MQe的消息和WMQ中的消息是完全不同的两种格式。所以,在前者到后者的消息传输前,网桥会对消息进行转换成WMQ的消息格式。WMQ目前不支持对MQe的消息解析,它只能把消息保存在本地队列中,让应用程序来完成解析。消息从WMQ队列到MQe队列时,网桥部分的消息转换模块会把消息转换为MQeMsgObject对象。MQeMsgObject是多个MQeFields组成,WMQ消息会作为其中一个MQeFields对象存在。
MQe的编程模型
MQe主要提供两种语言的应用编程接口:Java和C。
具体来说,Java语言可以细分为三大类的编程接口:
基于J2SE的API:提供对所有MQe功能的支持。包括消息加密认证,网桥等模块。 基于J2ME的API:在CDC/Foundation规范支持的CVM上,MQe提供与J2SE同样强大的API,视真实设备的硬件条件,这些API也可以选择性的被加载。在CLDC/MIDP规范支持的KVM上,MQe只提供客户端网桥管理器相关的API。 对JMS的支持:目前只支持Point-to-Point的编程模型,对Pub/Sub编程模型不支持。MQe对C语言的编程接口也可以分为下面几类:
C绑定接口:提供与MQe在J2SE平台上类似的API。但不支持存储发送队列和本地服务队列。 C本地接口:提供访问MQe大部分功能的API。但它不提供对网桥队列管理器的支持。并且,在消息加密和传输适配器协议的支持上,都有一定的限制。它是C绑定接口的一个子集。 对Palm的C接口:针对Palm OS提供MQe部分API,只支持客户端队列管理器。3. MQe与Websphere MQ集成的原型系统
在我们应用系统中,角色A向角色B发送即时消息。角色A的消息经过服务器端的路由,由服务器端对消息进行格式转换和内容处理后,再发送给角色B。这个流程涉及MQe和WMQ之间的集成。
具体来说,流程中的角色A和角色B都有一个Palm设备,在Palm OS里安装了MQe,并且安装基于MIDP的应用程序,这部分应用程序负责访问本地MQe和用户UI的工作。一个即时消息由角色A新建并发送到MQe Server上。MQe Server被配置成具有网桥功能,能把来自Palm上MQe的消息转发给WMQ。消息发送到WMQ的本地队列后,服务端在对消息相应处理之后,把消息发送回MQe Server。角色B会从MQe Server上的本地队列中读取处理过后的消息,MIDP应用程序把访问的结果显示在Palm设备上。流程图见图三:
图三 MQe与WMQ集成的流程图
配置MQe Server与WMQ
MQe Server是Palm设备上的MQe与WMQ通信的桥梁,所以它必须具备网桥的功能。我们借助MQe_Explorer来作配置工作,它是类似WMQ资源管理器的可视化工具。分下面6个步骤来完成这个操作。
1. 安装MQe和WMQ。运行MQe安装文件目录下的win32/setup.exe,选择安装的目录。MQe安装完毕后,安装MQe_Explorer。设置相应的Classpath,如果MQe的安装路径是C:/IBMJavasoft/MQe,MQe_Explorer的安装路径是C:/IBMJavasoft/MQe_Explorer,那么在Windows的环境变量Classpath后加上C:/IBMJavasoft/MQe/Java和C:/IBMJavasoft/MQe_Explorer/MQe_ExplorerV2.jar。
2. 运行MQe_Explorer,选择File>New>Queue Manager。输入队列管理器名字GateWayQM,选择配置信息存储的位置,默认其他选项。见图四。MQe的缺省的适配器MQeDiskFieldsAdapter会把所有的配置信息和消息写入Windows文件系统中。用户也可以选择其他适配器,例如MQeMemoryFieldsAdapter,它会把这些信息写到内存中。我们需要的是一个不会因为重启而丢失的信息的队列管理器,所以不能选择这个适配器。适配器选项在Detail属性页的Q adapter下拉框中可以选择。
图四 用MQe_Explorer传建MQe的队列管理器
启动这个简单的队列管理器有两种方式,用MQe提供的API编程,或者用MQe_Explorer来打开队列管理器配置信息,MQe将自动启动。通常在配置MQe的时候,我们选择后者,但是在应用运行的情况下,用自己编写的程序来启动MQe更为合适。
3. 然后用MQ资源管理器在WMQ中新建一个队列管理器WBRK_QM,设置为默认队列管理器。选择开始>程序> IBM WebSphere MQ > WebSphere MQ资源管理器,展开节点,选择队列管理器,右键新建>队列管理器。输入缺省的传输队列:TranQ。图五:
图五 用WMQ的资源管理器中新建队列管理器
这个向导总共有四个步骤,默认其他参数。在第四步中输入侦听端口1414。
4. 为队列管理器WBRK_QM新建本地队列、传输队列和服务器连接通道。
本地队列:PubQ,PubSubSycQ。PubQ保存来自MQe Server的消息。PubSubSycQ是GateWayQM和WMQ通信保存同步信息的队列。
传输队列:TranQ。在创建队列管理器的时候,我们已经设定TranQ就是缺省传输队列。
远程队列:SubQ。该队列指向GateWayQM上本地队列SubQ。我们用它测试从WMQ到MQe的消息传递是否成功。
服务端连接通道:BridgeChannel。它将侦听来自GateWayQM请求,并且建立连接。
要创建上述元素,可以用MQ的资源管理器,也可以在命令行下完成。在Windows命令行窗口下执行:runmqsc,然后输入下面的脚本。
DEFINE QLOCAL('PubQ') Persistent messages OK DEFINE QLOCAL('PubSubSycQ') Persistent messages OK DEFINE QLOCAL('TranQ') USAGE(XMITQ) DEFINE QREMOTE('SubQ') RNAME('SubQ') RQMNAGE('GateWayQM') XMITQ('TranQ') DEFINE CHANNEL('BridgeChannel') CHLTYPE( SVRCONN) END5. 配置MQe Server的网桥模块。打开MQe_Explorer,选择File>Open,找到MQe配置信息的文件路径,在这个例子中是C:/IBMJavasoft/MQe/GateWayQM.ini。选择确定后MQe Server配置信息会被读取,MQe Server启动。展开MQe root,出现一个树状结构,选取Bridges节点,鼠标右键选择弹出菜单中的New Bridge。在弹出的对话框中输入网桥的名字,其他都默认不改。网桥的名字可以随意取(但并不是所有MQe元素都可以随意命名,这将在后面可以看到),这里我们用BrokerBridge。
完成上述操作后,点击BrokerBridge这个节点,选择弹出菜单的New MQ Proxy,输入名字必须是WBRK_QM,它就是要连接的WMQ的QM名字。在Host栏里输入WMQ所在的机器IP地址。见图六。
图六 MQ Proxy的配置
选择刚才新建的MQ proxy节点,它的名字是WBRK_QM。右键选择弹出菜单中的New Client Conn。我们要为这个proxy新建一个到WMQ的连接,它的名字必须和WMQ的服务器连接通道一致,也就是BridgeChannel。见图七。
图七 Client Connection的配置信息。
这个对话框还有一个叫Detail的页,选择后你会发现很多可以选择的参数。在最简单的情况下,我们只需要输入WMQ 的侦听Port和WMQ上用于同步消息的队列,留下其他所有参数为默认值。
选取BridgeChannel这个节点,右键选择New Listener,新建一个MQe的侦听器。它的名字必须与WMQ上WBRK_QM的默认传输队列相同,也就是TranQ。我们的网桥配置基本完成,选择新建的BrokerBridge,启动它。如果看到Bridge run state是running则表示配置正确。
6. 网桥运行成功后,新建队列来测试MQe与WMQ之间消息交换。WMQ的队列管理器之间互相通信是通过发送方通道和接收方通道,而MQe与WMQ互相通信则要求建立一个到WMQ的连接和一个网桥队列。具体操作是选择Connections节点,New Connections。输入名字必须是WMQ中的队列管理器名字WBRK_QM。连接的类型选择Alias/MQ。
然后选择Local Queues节点,选择弹出菜单的New Queue,新建一个网桥队列。我们为这个队列输入名字:PubQ,它与WMQ的本地队列PubQ同名。输入队列的Destination属性:WBRK_QM。再选择队列的类型为Bridge。还有最重要的一步还没有做,就是选择Bridge属性页,输入对应的网桥信息。如图八。
图八 网桥队列的属性
现在我们可以通过MQe Server来向WMQ发送消息。选择新建的网桥队列PubQ,New Message会弹出一个消息对话框,输入消息的内容和编码方式等属性,点击确定。在看到Message Sent……的信息后,打开WMQ的资源管理器,展开WBRK_QM节点,选择队列:PubQ,浏览队列的消息。如果看到消息的内容与MQe中输入的内容一致,表明从MQe到WMQ的消息通道已经成功建立。
我们还需要验证WMQ同样可以把消息发送给MQe Server。在MQe Server中新建一个本地队列,默认所有属性,输入队列名SubQ。在本章节的先前部分,我们已经用MQ脚本语言为WBRK_QM建立了指向MQe中SubQ的远程队列,它的名字也是SubQ。进入Windows的命令行,输入amqsput SubQ WBRK_QM,回车后输入消息内容:Message from WMQ,再次回车。用MQe_Explorer查看SubQ的消息,如果看到来自WMQ的消息,表明WMQ到MQe的消息通道也已经成功建立。
到次,MQe Server的网桥功能已经配置完毕,MQe Server与WMQ的双向消息通道也已经建立。接下来我们要把消息扩展到移动设备上,让移动设备通过MQe Client,实现与MQe Server的通信,并且通过MQe Server,完成与内部系统的WMQ消息交换。
MQe Client for Palm
MQe对Palm有两种方式支持:用C实现的MQe Client和用MIDP实现的MQe Client。在这里我们采用基于MIDP的MQe Client,用IBM Websphere Micro Environment (WME)5.0作为J2ME的运行环境,用IBM Websphere Device Developer(WSDD)5.0作为J2ME应用的开发工具。WME的核心是IBM的J9虚拟机,和针对不同级别设备实现的API。J9支持Palm OS、Pocket PC在内的多种嵌入式系统。WSDD是基于eclipse技术的开发工具,它与WME紧密结合,开发的程序可以直接在WME中部署和运行。WSDD对Palm设备有着很好的支持,可以与Palm OS 3.5以上和4.X的Emulator和真实设备集成。用MIDP编写的程序可以通过WSDD直接在安装了WME的Palm Emulator和真实设备上运行和调试。WSDD还有微分析器,可以对程序占用系统资源等信息作出详细的分析。但是WME对Palm OS 5.0以上的设备和Simulator都不支持。对于安装了WME的Palm OS 4.X Emulator,MIDP中与UI相关的部分API,例如javax.microedition.lcdui.Form、javax.microedition.lcdui.List等,也不能正常的工作。
MQe并没有一个直接可以在Palm设备上安装的PRC格式的应用包,也没有类似MQe_Explorer的工具支持在Palm OS配置MQe。所以我们只能用API方式来配置和启动MQe。MQe安装目录下的Java/Jars/MQeMidp.jar,它包括MIDP环境下的MQe Client所需要的API。在WSDD中新建一个J2ME for J9,选择创建MIDP套件项目。见图九。在项目的特征中把MQeMIDP.jar作为外部Jar包加入。
图九 用WSDD新建一个MIDP套件项目
新建的项目要实现两个部分功能:MQe Client的核心部分;用户UI相关的逻辑。前者可以参考MQe安装目录下的Java/examples/midp/exampleapp/messageservice下面的类,它们用MIDP API实现一个MQe Client,并且操作管理这个队列管理器。改变这些类的包名后,把它们加入到项目中。具体分析,这些类的作用是:
MessageService:接口,它抽象了MQe基本操作,例如启动/停止队列管理器,新建队列,新建连接,发送/读取消息等。 MQeMessageService:用MIDP API和MQe MIDP API(MQeMIDP.jar),实现了MessageService接口。只要得到这个类的实例,就可以完成对MQe的所有操作。 QueueManagerRules:在MIDP环境下,为队列管理器定制规则。 MQeMessageServiceConstants:接口,与MQe相关的属性常量都在这里定义。 MQeMessageServiceParameters:实现了MQeMessageServiceConstants接口,用一组getter/setter方法提供对接口中定义的字段的访问。值得注意的是,MIDP环境中的MQe Client和MQe Server有很多区别,例如用MQeMidpHttpAdapter作为队列管理器间消息传输协议;用MQeMidpFieldsAdapter把队列管理器配置信息存储到MIDP的RecordStore中。对开发人员来说,选择messageservice目录下的这些类就可以避免自己处理这些底层问题。在这部分代码的基础上,剩下的工作就是编写逻辑代码来确定何时启动关闭MQe、何时发送消息,发送怎么样的消息内容和发送到哪个远程队列。
编写逻辑相关的类时,我们将指定MQe Client的队列管理器名字(MobileQM)、MQe Server的IP地址、队列管理器的名字(GateWayQM)、远程队列的名字(TempPubQ)等。我们用MessageService接口里面的方法来创建到GateWayQM的Connection和远程队列指向GateWayQM上的本地队列TempPubQ,然后启动MobileQM。应用程序用Midlet来实现,它是在MIDP环境中运行的小程序。我们为消息发送者A和消息接受者B分别设计对应的Midlet。角色A的SenderMidlet类在startAPP()方法中实例化控制队列管理器的类(MQeMessageService),创建MobileQM,并使它处于active 状态。在取得输入的即时消息后,SenderMidlet调用负责发送的SenderModelClient类中的send()方法,向MQe Server发送消息。这部分的代码如下:
public void send() { try { MQeMsgObject msg = new MQeMsgObject(); msg.putUnicode("MessageContent", strMsgContent); //发送者输入的消息内容 msg.putInt(MQe.Msg_ExpireTime, 900000); //设置消息的失效时间 // 得到MessageService实例,用它把消息发到MQe Server上的目的队列。 getMsgService().sendMessage(serverQMname, serverQname, msg); processStatus(" Message has been sent. " ); //把操作结果用SenderMidlet中的javax.microedition.TextBox组件显示给发送者。 }catch (Exception e) { e.printStackTrace(); processStatus(" Unable to sent message, try again" ); } }在把这部分程序部署到Palm设备上前,我们需要把它打成PRC格式的安装包。WSDD支持把Java类编译成Palm设备可以执行的代码,并打成PRC安装包。可以通过在wsddbuild.xml中添加一个Palm平台的构建来完成。但是WSDD 5.0的编译器有一定的缺陷,它的优化机制常常会作出错误的判断,会把一些外部Jar里的类不放到PRC包中,从而在执行构建发生类找不到的错误。解决这个问题的方法是打开构建的属性文件,选择包括/排除属性,添加我们所要用到的API,强制编译器去读取这些类。在这个的项目中,我们指明类的包名,防止类丢失。图十。
图十 编辑构建的属性信息
消息的接受者B是一个类似的MIDP应用。它从MQe Server的队列中取回消息,在WME环境中用MIDP的RecordStore存储所有的即时消息,维护一个类似手机短信的消息管理模块。同样,角色B的ReceiverMidlet首先需要创建并激活本地的客户端队列管理器(MobileQM),所以它也要借助messageservice包内的类。在MobileQM成功启动后,ReceiverMidlet启动一个线程,从GateWayQM上的本地队列中读取消息。这里用Browse,而不是Get方式读取消息,因为角色B对应的是多个实体,他们都需要取得消息内容。角色B在取得消息后,首先与RecordStore中的消息记录比较,判断是否新消息,如果是才会做相应处理。
public void run() { while(true) { Vector vec = new Vector(); //得到MessageService实例,用browse的方式取得队列中所有的消息 getMsgService().browseMessages(serverQMname, serverQname, null, null, 0, false, vec); //把Vector中的消息逐个与RecordStore中的消息作比较。 for(int i = 0; i < vec.size(); i++) { MQeMsgObject msg = (MQeMsgObject)vec.elementAt(i); if(!detectMsg(msg)) //判断当前是否是新的消息。 { //是新的消息,把它放到RecordStore中存储起来,在UI模块中提示用户。 RMSMsgRepository rep = new RMSMsgRepository(); ................. //存储消息,提示接受者有新消息到来等操作。代码省略。 }else { Thread.sleep(3000); //如果不是新的消息,等待一下。 } } } }角色B收到的消息在Palm Emulator的显示如图十一:
图十一 Palm Emulator上的消息列表
集成MQe Client、MQe Server和WMQ
到目前为止,这个流程还不能正常运作。让我们来看看还要做哪些努力。
1. 在GateWayQM上新建一个Comms Listeners,侦听来自Palm设备上MobileQM的消息。这个操作相当简单,要注意的是在选择侦听器的Adapter的时候一定要选择MQeTcpipHttpAdapter。此外,它侦听的端口与MobileQM中指定的MQe_Server_Port要相同。
2. 我们已经知道MobileQM把消息发给GateWayQM,由后者把消息发给WMQ中的WBRK_QM,再由服务器端对消息做对应处理。问题是GateWayQM中的网桥队列PubQ是一种特殊的远程队列,所以在MobileQM中我们无法新建一个指向远程队列的远程队列。这听上去有点拗口,换个角度说,远程队列只能指向另外一个队列管理器中的本地队列。解决的方案是在GateWayQM中新建一个临时的本地队列TempPubQ,MobileQM先把消息发到该队列,然后再运行一个应用程序来从临时的本地队列中读取消息,验证消息的合法性后放到网桥队列PubQ。
3. 消息从GateWayQM发到WBRK_QM后的流程。在我们的应用系统中,WBI Message Broker对消息做一个简单的Pub/Sub的流程。最终,GateWayQM会以Pull的方式从WBRK_QM的SubQ中取回消息。
我们重点看一下第二个问题,它与本文的主题相关密切。在文章开始部分曾提到,在配置MQe的时候MQe_Explorer是个非常好的工具,但是在应用开发完毕要正式使用的时候,它却不是最好的选择。MQe_Explorer不像MQ资源管理器,后者提供完整的编程接口来让开发者操作内部的对象和消息。MQe_Explorer不提供任何这样的接口,所以我们要自己新建一个项目来启动这个已经配置完毕的队列管理器,并且完成消息从TempPubQ到PubQ的转移。实现这两个部分并不复杂,新建一个普通Java项目,把MQe安装目下的Java/examples/queuemanager类加到其中,并且在为项目添加两个外部Jar包:MQe_ExplorerV2.jar和MQeGateway.jar。其中启动队列管理器的代码如下:
public String start() { //读取配置GateWayQM信息,用MQeServer类来启动它。 MQeServer gw = new MQeServer("C://IBMJavaSoft//MQe//GateWayQM.ini"); try { gw.activate(true); //没有抛出异常,表示队列启动成功。 return "done"; } catch (Exception e) { System.out.println("Error: activate() failed. " + e.toString()); return "Error: Start MQ Everyplace GateWay QM failure"; } }最后,让我们打开WBI Message Broker,看一下这个简单的Pub/Sub流程。消息从PubQ队列中输入后,首先会在Compute节点上做具体的逻辑处理。如果处理正确,消息会流转到Trace节点,由它把消息内容写到本地的Log文件中。如果消息处理失败,消息将流转到会放到MQFailure节点所指定的队列中。Publication节点告诉WBRK_QM的SYSTEM.BROKER.CONTROL.QUEUE根据消息的Topic把消息发送给对应的订阅者,在我们的项目中它是SubQ。图十二。
图十二 一个简单的Pub/Sub流程
4 结论
MQe和WMQ的结合,让IBM的MQ产品家族触及到更加广泛的领域。本文重点介绍了MQe这个产品,和用Java开发MQe,以及MQe与WMQ集成的具体方法