时间:2006-06-27 作者:孟和 浏览次数: 1229 本文关键字:WebLogic, MQ, JMS, MQSeries, JMS Bridge |
|
最近参与一个系统的原型开发,原型要求演示WebLogic Server9.1与其他第三方产品的通信支持,包括与IBM MQSeries的双向交互、与Tuxedo的双向交互、支持与.NET的通过Web Service交互等。我负责完成与IBM MQSeries的双向交互这部分,在网上找了不少文章,发现其中基本都是基于WebLogic Server 8.1实现的。因为WebLogic Server 9.1在JMS上有很大的增强,所以我参考以前的文章,自己实现了WebLogic Server 9.1与IBM MQSeries 5.3的双向交互并且进行了测试。想必很多同行会遇到跟我一样的问题,特此撰文一片跟大家分享。本文配置在window xp上测试成功。
概述
目标是实现WebLogic Server 9.1和IBM MQSeries5.3之间的的双向交互,包括:
- WebLogic Server 9.1消息转发给IBM MQSeries5.3
- IBM MQSeries 5.3消息转发给WebLogic Server 9.1
具体地,将WebLogic Server9.1队列WLSSendQueue的消息转发到IBM MQSeries 5.3队列MQReceiveQueue,同时将IBM MQSeries 5.3队列MQSendQueue的消息转发到WebLogic Server 9.1队列WLSSendQueue。
WebLogic Server包含一个完整的、有丰富特性的消息服务器。第三方的消息服务器(如IBM MQSeries),只要其提供了JMS API的实现,也可以在其中运行。Messaging Bridge是一种由WebLogic Server提供的J2EE设备,用于转发两个消息提供者的消息。你可以使用Messaging Bridge将消息从一个消息提供者的目的地(队列或者主题)移至另外一个消息提供者的目的地。因此,当WebLogic应用程序需要与第三方消息提供者 (比如IBM MQSeries)进行交互时,Messaging Bridge就可以承担这个中间角色。我们需要做如下配置:
- 通过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必须安装在同一台机器上。
WLS配置
WebLogic Server 9.1在WebLogic JMS的配置、部署和动态管理方面引入了重要的改进。它对JMS 1.1规范提供官方支持。此外,在系统中添加了人们期待已久的消息排序高级特性。XML API的XML消息处理功能得到了增强。在WebLogic 9.1平台上使用JMS非常轻松有趣、可靠且迅速。下面是现有新特性中的一些亮点。
- 自动化的 JMS 故障恢复
自动化的JMS故障恢复是业内期待已久的特性。JMS利用“Automatic WebLogic Server Migration”特性来提供自动化的JMS故障恢复。在整个WebLogic Server实例进行故障恢复时,JMS也将自动从故障中恢复过来。尽管其他的一些JMS服务器提供商已经利用一些复杂装置提供了这样的功能,但 WebLogic 9.1的实现是最直观而清晰的。
- 排序单元
消息排序是大多数消息处理应用程序的一项基本要求。WebLogic Server JMS即使在集群环境中也能确保消息的顺序处理。它甚至可以定义多个组来将消息分组,这样每个组都拥有自己的处理顺序(如图1所示)。
- 存储转发 (SAF)
WebLogic存储转发(store and forward, SAF)服务使WebLogic Server能在通过WebLogic Server实例部署的应用程序间可靠地交付信息。SAF的强大功能使得我们可以很容易地将多个消息服务链接在一起(如图2所示)。
- Messaging Bridge具有如下优点:
- 不需要编码,纯配置,加速你的开发;
- 灵活的体系结构,容易配置多个Messaging Bridges,并且而且可以动态的启动和停止单个Messaging Bridge;
- 采用即取即用的MQ 适配器,实现全面的MQ JMS 支持,能够设定MQ 主题查询;
- 充分利用WebLogic容器进行服务管理,并且集中所有的Bridges资源在一个线程池;
- 全面的事务处理能力,两阶段事务处理;
- 全面的JCA 支持;
- 确保服务质量和连接管理,实实在在的一次性服务;
- 控制台监视能力;
- 集成BEA WebLogic应用与外部消息提供商,以便将新的应用与现有的投资连接起来。
创建Server域
创建Server Domain, domain名称jms_domain
修改启动文件
修改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=D:\installed\MQ set MQ_JAVA_INSTALL_PATH=D:\installed\MQ\Java 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% set CLASSPATH=%MQ_CLASSPATH%;%WEBLOGIC_CLASSPATH%; %POINTBASE_CLASSPATH%;%JAVA_HOME%\jre\lib\rt.jar; %WL_HOME%\server\lib\webservices.jar;%CLASSPATH%
配置JMS
注意WLS91的连接工厂和队列要到JMS Modules下面设置:
- 创建文件后备存储BridgeFileStore
- 创建JMS服务器BridgeJMSServer,和Paging Store设为" BridgeFileStore" ,Target为adminServer
- 创建支持XA的连接工厂WLSCFXA,JNDI Name为bridge.wlsCFXA
- 创建JMS发送队列WLSSendQueue,JNDI名称为bridge.wlsSendQueue,Target为BridgeJMSServer
- 创建JMS接收队列WLSReceiveQueue,JNDI名称为bridge.wlsReceiveQueue,Target为BridgeJMSServer
配置Messaging Bridge Destination
- JMS Bridge Destination名称为MQReceiveBridgeDestination
- Adapter JNDI Name: eis.jms.WLSConnectionFactoryJNDIXA
- Connection URL为file:/D:/installed/MQ/Queues,
- Initial Context Factory为com.sun.jndi.fscontext.RefFSContextFactory,
- Connection Factory JNDI Name为bridge.mqQCFXA,
- Destination JNDI Name为bridge.mqReceiveQueue
- Destination Type: Queue
- JMS Bridge Destination名称为MQSendBridgeDestination
- Adapter JNDI Name: eis.jms.WLSConnectionFactoryJNDIXA
- Connection URL为file:/D:/installed/MQ/Queues,
- Initial Context Factory为com.sun.jndi.fscontext.RefFSContextFactory,
- Connection Factory JNDI Name为bridge.mqQCFXA,
- Destination JNDI Name为bridge.mqSendQueue
- Destination Type: Queue
- JMS Bridge Destination名称为WLSReceiveBridgeDestination
- Adapter JNDI Name: eis.jms.WLSConnectionFactoryJNDIXA
- Connection URL为t3://localhost:7001,
- Initial Context Factory为weblogic.jndi.WLInitialContextFactory,
- Connection Factory JNDI Name为bridge.wlsCFXA,
- Destination JNDI Name为bridge.wlsReceiveQueue
- Destination Type: Queue
- User Name: weblogic(域配置时指定的)
- User Password: weblogic(域配置时指定的)
- JMS Bridge Destination名称为WLSSendBridgeDestination
- Adapter JNDI Name: eis.jms.WLSConnectionFactoryJNDIXA
- Connection URL为t3://localhost:7001,
- Initial Context Factory为weblogic.jndi.WLInitialContextFactory,
- Connection Factory JNDI Name为bridge.wlsCFXA,
- Destination JNDI Name为bridge.wlsSendQueue,
- Destination Type: Queue
- User Name: weblogic(域配置时指定的)
- User Password: weblogic(域配置时指定的)
配置Messaging Bridge
- JMS Bridge名称为MQ2WLSBridge
- Source Bridge Destination: MQSendBridgeDestination
- Target Bridge Destination: WLSReceiveBridgeDestination
- Quality Of Service: Exactly-Once
- Started: Yes
- JMS Bridge名称为WLS2MQBridge
- Source Bridge Destination: WLSSendBridgeDestination
- Target Bridge Destination: MQReceiveBridgeDestination
- Quality Of Service: Exactly-Once
- Started: Yes
MQ 配置
IBM MQSeries是IBM的商业通讯中间件(Commercial Messaging Middleware)。IBM MQSeries提供一个具有工业标准,安全,可靠的信息传输系统。它的功能是控制和管理一个集成的商业应用,使得组成这个商业应用的多个分支程序(模块)之间通过传递信息完成整个工作流程。IBM MQSeries具有特殊的技术防止信息重复传送,确保信息一次且仅一次(once-and-only-once)传递,保证传输的可靠性。本文使用的 MQ版本为IBM MQSeries 5.3。
IBM MQSeries基本由一个消息传输系统和一个应用程序接口组成,其资源是消息和队列(Messaging and Queuing)。
队列管理器(Queue Manager):管理队列的系统,实现网络通信,保证消息安全可靠地传输到目的地。用于确保队列之间的信息提供,包括网络中不同系统上的的远程队列之间的信息提供。并保证网络故障或关闭后的恢复。
队列:一个安全的信息存储区。因为信息存放在队列中,所以应用程序可以相互独立的运行,以不同的速度,在不同的时间,在不同的地点。
本地队列:对程序而言,本地队列属于该程序所连接的队列管理器。
远程队列:该队列不属于该程序所连接的队列管理器,而只是远端队列管理器的队列在本地的定义。
传输队列:它是一个本地队列,保存了指定要发送到远端的消息。
死信队列:它是一个本地队列,用于存放无法传递的消息。
通道:在两个队列管理器之间建立起来的数据传输链路。
应用程序接口:应用程序和信息系统之间通过MQSeries API实现的接口。
Install MQ
- 安装过程中选择自定义安装模式,并确保安装JMS所需的Java jar包支持如下图:
(缺省安装未包含)
确认MQ服务已启动。
可通过MicroSoft windows控制面板中管理工具下的服务控制台确认。如下图:
从程序菜单启动MQ 资源管理器
如果程序提示试用版过期,可以通过修改系统时间搞定.我就是修改到了2004年。
通过MQ资源管理器创建一个通道
建立名为BRIDGE.CHANNEL的通道,其他参数缺省设置。
通过MQ资源管理器创建两个本地队列
建立两个本地队名为MQReceiveQueue, MQSendQueue,其他参数缺省设置。
更新MQ安装目录下与JMS配置相关的文件
JMSAdmin.config文件位于%MQ_INSTALLL_HOME_PATH%\Java\bin,主要定义JNDI服务的提供商,即JMS Server Factory和URL。%MQ_INSTALLL_HOME_PATH%\Java\bin目录下新建目录bridgeconfig,将JMSAdmin.config文件拷贝到bridgeconfig。
使用Sun的文件JNDI服务Factory,故定义
INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory PROVIDER_URL=file:/D:/installed/MQ/Queues SECURITY_AUTHENTICATION=none (例子中,MQ安装目录%MQ_INSTALLL_HOME_PATH%为:D:/installed/MQ/) JMSAdmin.bat文件也位于%MQ_INSTALLL_HOME_PATH%\Java\bin,此文件用于启动MQ的JMS命令行管理界面,要设置启动JMS命令行管理界面所需环境变量。在JMSAdmin.bat中添加如下环境变量: set MQ_JAVA_INSTALL_PATH=D:\installed\MQ\Java 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
进入MQ的JMS命令行管理界面绑定MQ的JMS Factory以及JMS本地队列
- 开启MicroSoft Windows的Dos窗口(cmd.exe)
- 进入MQ安装目录下的java目录下的bin目录
- 运行JMSAdmin.bat并通过-cfg参数指定JMSAdmin.config文件位置
本次例子中输入:D:\ installed\MQ\Java\bin>jmsadmin -cfg .\bridgeconfig\jmsadmin.config
- 如上图所示界面,生成一个MQXAQueueConnectionFactory对象,Messaging Bridge将使用这个工厂对象建立MQ的XA连接,使用命令DEFINE XAQCF,起名:bridge.mqQCFXA。
- 生成JMSQueue对象来绑定MQ队列MQReceiveQueue。
- 生成JMSQueue对象来绑定MQ队列MQSendQueue。
- 使用dis ctx命令,查看目前已有的对象和绑定,可以看到XA连接工厂和队列都已绑定。
测试
MQ发送,WLS接收
- MQ发送队列放入测试消息
- 在WLS控制台监测消息到达
WLS发送,MQ接收
- WLS发送队列放入测试消息
执行下面的代码,给WLS发送队列放入测试消息
package com.bea; import javax.naming.InitialContext; import javax.naming.Context; import javax.naming.NamingException; import javax.jms.*; import java.util.Hashtable; /** * Created by IntelliJ IDEA. * User: pmeng * Date: 2006-6-3 * Time: 14:54:08 */ public class SendMessageTest { public static void main(String[] args) { try { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); env.put(Context.PROVIDER_URL, "t3://localhost:7001"); InitialContext ctx = new InitialContext(env); QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("bridge.wlsCFXA"); QueueConnection connection = factory.createQueueConnection(); QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); Queue queue = (Queue) ctx.lookup("bridge.wlsSendQueue"); connection.start(); QueueSender queueSender = session.createSender(queue); TextMessage msg = session.createTextMessage(); msg.setText("Menghe."); queueSender.send(msg); } catch (NamingException e) { System.out.println("NamingException:" + e.getMessage()); e.printStackTrace(); } catch (JMSException e) { System.out.println("JMSException:" + e.getMessage()); e.printStackTrace(); } } }
- MQ资源管理器查看接收到的消息
参考资料
- BEA WebLogic Server 8.1 JMS与 IBM MQSeries 集成方案,周海根,
http://dev2dev.bea.com.cn/techdoc/20040411784.html - BEA WebLogic 8.1 JMS 与IBM MQ v5.3 通过JMS Message Bridge通信配置,陈仁祥
http://e-docs.bea.com/wls/docs91/messaging.html