本文主要在讲述BEA WebLogic Server8.1 JMS和Messaging Bridge的基本概念及其优势的基础上,并图文并茂的讲解BEA WebLogic Server8.1 JMS与第三方消息中间件IBM MQSeries5.2 进行事务性消息转发的集成方案。IBM MQSeries的基本概念也将被涉及。
关键字:WebLogic Server,JMS,MQSeries,连接工厂, JMS服务器,Messaging Bridge,队列,队列管理器,通道,消息驱动Bean
How to user messageing bridge in BEA WebLogic Sever8.1 to transfer messages transactionally between BEA WebLogic Sever8.1 Queues and IBM MQSeries Queues?
In this paper,we will desribe the BEA WebLogic Sever8.1 JMS and Messaging Bridge concept and their benefits.On this base,we will graphicly and literally demonstrate how to set up messaging bridges to transfer messages transactionally between BEA WebLogic Sever8.1 Queues and IBM MQSeries Queues.Also,the IBM MQSeries concept will be touched.
Key words: WebLogic Server,JMS,MQSeries,Connection Factory, JMS Server,Messaging Bridge,Queue,QueueManager,Channel,MDB
1 基础知识简介
1.1 JMS简介
1.2 Messaging Bridge简介
1.3 IBM MQSeries简介
2 事务性集成方案简介
2.1 方案概览
2.2 前期准备
3 配置MQ
3.1 配置队列管理器
3.2 配置服务器连接通道
3.3 配置队列
3.4 绑定JMS对象
4 配置WebLogic
4.1 创建Server域
4.2 修改启动文件
4.3 部署JCA适配器
4.4 配置JMS
4.5 配置Messaging Bridge
5 设计Messaging Bridge应用程序
5.1 设计消息发送端
5.2 设计消息接收端
5.3 部署MDB
6 测试Messaging Bridge
6.1 测试WLS2MQBridge
6.2 测试MQ2WLSBridge
7 另辟蹊径
8 问题
9 总结
JMS(Java Message Service)是访问企业消息系统的标准API,它便于消息系
统中的Java应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接口简化企业应用的开发。
WebLogic Server包含一个完整的、有丰富特性的消息服务器。第三方的消息服务器(如IBM MQSeries),只要其提供了JMS API的实现,也可以在WebLogic Server中运行。想了解更为详细的JMS基础知识可以参考文章BEA WebLogic Server8.1 JMS入门。
什么是Messaging Bridge呢?它是一种由WebLogic Server提供的J2EE设备,用于转发两个消息提供者的消息。你可以使用Messaging Bridge将消息从一个消息提供者的目的地(队列或者主题)移至另外一个消息提供者的目的地。因此,当WegLogic应用程序需要与第三方消息提供者(比如IBM MQSeries)进行交互时,Messaging Bridge就可以承担这个中间角色。
Messaging Bridge具有如下优点:
不需要编码,纯配置,加速你的开发;
灵活的体系结构,容易配置多个Messaging Bridges,并且而且可以动态的启动和停止单个Messaging Bridge;
采用即取即用的MQ 适配器,实现全面的MQ JMS 支持,能够设定MQ 主题查询;
充分利用WebLogic容器进行服务管理,并且集中所有的Bridges资源在一个线程池;
全面的事务处理能力,两阶段事务处理;
全面的JCA 支持;
确保服务质量和连接管理,实实在在的一次性服务;
控制台监视能力;
集成BEA WebLogic应用与外部消息提供商,以便将新的应用与现有的
投资连接起来。
IBM MQSeries是IBM的商业通讯中间件(Commercial Messaging Middleware)。IBM MQSeries提供一个具有工业标准,安全,可靠的信息传输系统。它的功能是控制和管理一个集成的商业应用,使得组成这个商业应用的多个分支程序(模块)之间通过传递信息完成整个工作流程。IBM MQSeries具有特殊的技术防止信息重复传送,确保信息一次且仅一次(once-and-only-once)传递,保证传输的可靠性。本文使用的MQ版本为IBM MQSeries 5.2。
了解完JMS,Messaging Bridge和MQ的基本概念后,让我们看看是怎么使用Messaging Bridge,实现WebLogic Server8.1 JMS和IBM MQSeries5.2的事务性集成方案的。
我们的目标是实现WebLogic Server8.1和IBM MQSeries5.2之间的事务性消息转发:包括WebLogic Server8.1消息转发给IBM MQSeries5.2,以及IBM MQSeries5.2消息转发给WebLogic Server8.1。具体地,将WebLogic Server8.1队列WLSSendQueue的消息转发到IBM MQSeries5.2队列MQReceiveQueue,同时将IBM MQSeries5.2队列MQSendQueue的消息转发到WebLogic Server8.1队列WLSSendQueue。
我们需要做如下配置,下图为方案的体系结构:
通过WebLogic控制台建立两个WebLogic队列:发送队列WLSSendQueue和接收队列WLSReceiveQueue。 类似地,通过MQ资源管理器建立两个MQ本地队列:发送队列MQSendQueue和接收队列MQReceiveQueue。 为了实现消息转发需要建立两个Messaging Bridge:WLS2MQBridge 和MQ2WLSBridge 。WLS2MQBridge:将WebLogic发送队列WLSSendQueue的消息转发到MQ接收队列MQReceiveQueue;MQ2WLSBridge:将MQ发送队列MQSendQueue的消息转发到WebLogic接收队列WLSReceiveQueue。 为了实现事务性消息转发, WebLogic需要使用XAQueueConnectionFactory,而MQ需要使用MQXAQueueConnectionFactory。这就确定了WebLogic需要使用支持XA的连接工厂,MQ必须采用绑定的模式,并且WebLogic和MQ必须安装在同一台机器上。Messaging Bridge通过WebLogic Server提供的J2EE Connector Architecture JMS Adapter(J2EE连接器体系结构——JMS适配器)与WebLogic JMS队列连接,同时Messaging Bridge也是通过WebLogic Server提供的J2EE Connector Architecture JMS Adapter与MQ队列连接。
Messaging Bridge服务质量等级有三种:Exactly-Once, Almost-Once,Duplicate-Okey。三者可靠性依次降低,根据不同服务质量等级,WebLogic Server8.1提供有四种JMS JCA适配器:
jms-xa-adp.rar: Exactly-Once(仅一次)
jms-notran-adp.rar: Almost-Once(至多一次)或者Duplicate-Okey(至少一次)
jms-local-adp.rar: Duplicate-Okey(至少一次),不常用
jms-notran-adp51.rar: 与WebLogic Server 5.1的JMS交互,与jms-notran-adp.rar类似。
方案要求实现事务性消息转发,所以我们必须让Messaging Bridge提供Exactly-Once 的服务质量。JMS JCA适配器使用MQ JMSAdmin工具产生的JNDI对象来连接MQ队列,为了提供Exactly-Once的服务质量,JMS JCA适配器必须使用MQXAQueueConnectionFactory JNDI对象来与MQ连接。可是MQ JMSAdmin工具仅支持在binding模式(绑定模式)下产生MQXAQueueConnectionFactory JNDI对象。MQ JMS驱动器在client模式(客户端模式)下并不支持分布式事务。而在绑定模式下,MQ采用文件系统来绑定对象,必须是本机才能访问。
因此,为了让Messaging Bridge提供Exactly-Once 的服务质量,WebLogic Server8.1和MQ必须运行在同一台机器上。假如Exactly-Once的服务质量不是必须的,MQSeries可以和WebLogic Server运行在不同的机器上。
在继续我们的方案讨论之前,我们需要在Windows2000操作系统下安装下列软件:
安装BEA WebLogic Server8.1的详细步骤请参考BEA dev2dev学堂文章:跟我学WebLogic Server之一 --如何安装BEA WebLogic Server。
安装IBM MQSeries5.2 Windows2000版本,注意:MQ安装目录(C:MQSeries)最好自定义,且不含空格。安装完成后,可以用明信片的例子验证安装正确性。相关软件可以到以下链接下载:http://www.ibm.com/software/ts/mqseries/downloads。
安装MQSeries classes for Java和MQSeries classes for Java Message Service 以提供JMS驱动,使用JMSAdmin工具,注意:安装目录(C:MQSeriesJava)最好与MQSeries的安装目录一致。相关软件可以到以下链接下载:http://www.ibm.com/software/ts/mqseries/txppacs/ma88.html。
安装MQSeries SupportPac MA0C以支持Topic,支持发布/订阅模式,本文可以略过。相关软件可以到以下链接下载:http://www.ibm.com/software/ts/mqseries/txppacs/ma0c.html。
首先,确认MQ已经启动。如果MQ没有启动,则通过控制面板/管理工具/服务启动IBM MQSeries服务。
MQ的配置有两个方式:一种是采用MQ资源管理器;另一种是采用MQ命令行。在MQ资源管理器中配置,简单直观,由于本文并不着重研究MQ,因此采用MQ资源管理器的方式配置MQ资源。
创建队列管理器可以使用MQ资源管理器,也可以使用MQ基本操作命令:crtmqm -q QM_TestBridge,其中-q是指创建缺省的队列管理器。为简单直观起见我们采用MQ资源管理器来创建队列管理器:
从程序/IBM MQSeries子栏中,打开IBM MQSeries资源管理器; 右键IBM MQSeries的子节点,点击"新建""队列管理器"; 创建默认的队列管理器QM_TestBridge,设置为缺省的队列管理器; 以下都按默认配置,输入监听端口1414(MQ专用端口)。
按照创建本地队列MQReceiveQueue的做法,创建本地队列MQSendQueue。
使用MQ JMSAdmin命令行工具生成被管理的JMS对象。在安装了MQSeries Client for Java之后,在%MQ_JAVA_INSTALL_PATH%/in目录下找到JMSAdmin.config文件。该文件主要用来说明Context的存储方式及存储地址,对应于文件中的两个参数INITIAL_CONTEXT_FACTORY和PROVIDER_URL。典型的JMSAdmin.config文件内容如下:
#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使用的服务提供商。当前有三种受支持的值。com.sun.jndi.ldap.LdapCtxFactory用于LDAP,如果使用它就必须安装一个LDAP服务器。com.sun.jndi.fscontext.RefFSContextFactory用于文件系统上下文,它只需要使用者提供存放上下文的文件路径。com.ibm.ejs.ns.jndi.CNInitialContextFactory是专门为websphere提供的,它需要和websphere的CosNaming资源库一起使用。
PROVIDER_URL表示会话初始上下文的URL,由JMSAdmin tool实现的所有JNDI操作的根。它和INITIAL_CONTEXT_FACTORY一一对应:
ldap://hostname/contextname 用于LDAP;
file:[drive:]/pathname 用于文件系统上下文;
iiop://hostname[:port]/[?TargetContext=ctx] 用于访问websphere CosNaming名称空间。
最后还有一个参数SECURITY_AUTHENTICATION,用于说明JNDI是否把安全性凭证传递给了您使用的服务供应商。只有当使用了LDAP服务供应商时,才使用此参数。此参数有三个值,none(匿名认证)、simple(简单认证)和CRAM-MD5认证机制。如果没有提供有效值,缺省值为none。
在使用MQ JMSAdmin命令行工具之前,我们应该使用我们自己的配置文件来运行JMSAdmin。JMSAdmin.config位于%MQ_JAVA_INSTALL_PATH%/bin目录下,备份JMSAdmin.config文件到新建目录bridgeconfig下,然后修改这个文件的三个变量值:
INITIAL_CONTEXT_FACTORY使用文件系统上下文:
INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory
PROVIDER_URL为任意的文件目录,文件名不能包含空格
PROVIDER_URL=file:/C:/mqseries/JNDI
安全授权为NONE
SECURITY_AUTHENTICATION=none
备份%MQ_JAVA_INSTALL_PATH%/bin目录下的jmsadmin.bat文件,修改jmsadmin.bat。这个文件用来启动JMSAdmin工具,我们需要将ibm类包包含在类路径下:
set MQ_JAVA_INSTALL_PATH=C: MQSeriesjava set MQ_JAVA_LIB=%MQ_JAVA_INSTALL_PATH%lib set MQ_CLASSPATH=%MQ_JAVA_LIB%com.ibm.mq.jar set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%com.ibm.mqbind.jar set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%com.ibm.mqjms.jar set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%fscontext.jar set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%jms.jar set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%jta.jar set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%ldap.jar set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%providerutil.jar修改后的JMSAdmin.bat文件如下图所示:
使用刚刚自定义的配置文件,启动JMSAdmin工具:到%MQ_JAVA_INSTALL_PATH%/bin下,运行命令:jmsadmin -cfg ./ridgeconfigjmsadmin.config。
在新窗口出现InitCtx命令提示,表明已经开始一个MQSeries JMSAdmin 会话。使用dis ctx命令查询已经存在的被管理的JNDI 对象,可以看到目前并没有对象。
生成一个MQXAQueueConnectionFactory对象,Messaging Bridge将使用这个工厂对象建立MQ的XA连接,使用命令DEFINE XAQCF,起名:bridge.mqQCFXA。
使用DEFINE Q命令,生成JMSQueue对象来绑定MQ队列MQReceiveQueue。
同理,使用DEFINE Q命令,生成JMSQueue对象来绑定MQ队列MQSendQueue。
再次使用dis ctx命令,查看目前已有的对象和绑定,可以看到XA连接工厂和队列都已绑定。注意到,我们在绑定队列并没有指明队列的队列管理器名称,是因为我们队列对应的队列管理器是默认的队列管理器。否则我们需要使用下面的命令来绑定队列:DEFINE Q(jndiName) QUEUE(qName) QMGR(qMName)。
确认后,用END命令退出JMSAdmin工具。
创建Server Domain(domain名称:mydomain),假如已经有了,就不用创建了,建议采用开发模式(默认配置)。具体的创建步骤请参考:
http://e-docs.bea.com/platform/docs81/confgwiz/tutorials.html#1055856
修改WebLogic的启动文件startWebLogic.cmd。将IBM MQSeries和IBM MQSeries Java的安装目录加到WebLogic path下,同时将MQ JMS Java类包加入到WebLogic classpath下:
@rem added the following to configure messaging bridge with local MQSeries installation @set MQ_INSTALL_PATH=C:MQSeries @set MQ_JAVA_INSTALL_PATH=C:MQSeriesjava @set MQ_JAVA_LIB=%MQ_JAVA_INSTALL_PATH%lib @set MQ_CLASSPATH=%MQ_JAVA_LIB%com.ibm.mq.jar @set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%com.ibm.mqbind.jar @set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%com.ibm.mqjms.jar @set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%fscontext.jar @set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%jms.jar @set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%jndi.jar @set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%jta.jar @set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%ldap.jar @set MQ_CLASSPATH=%MQ_CLASSPATH%;%MQ_JAVA_LIB%providerutil.jar @set MQ_PATH=%MQ_INSTALL_PATH%/in;%MQ_JAVA_INSTALL_PATH%/in; %MQ_JAVA_INSTALL_PATH%lib @set PATH=%MQ_PATH%;%PATH% @setCLASSPATH=%MQ_CLASSPATH%;%WEBLOGIC_CLASSPATH%; %POINTBASE_CLASSPATH%;%JAVA_HOME%jrelib t.jar; %WL_HOME%serverlibwebservices.jar;%CLASSPATH%
修改启动文件后,将JCA适配器包