在面向消息的中间件(MOM)这个领域,IBM MQSeries (又称WebSphere MQ)一直是当仁不让的超级大哥,其它还有一些小兄弟,比如SwiftMQ、SonicMQ之类。但近年来随着J2EE中的JMS规范的建立,完备地支持JMS的服务器如雨后春笋般地出现,比如BEA WebLogic Server的JMS Server就是其中一个佼佼者。
仅仅就JMS规范来说,MQSeries与WebLogic JMS没有什么不同之处。但JMS规范仅仅定义了消息服务器的一个开发接口,而且还忽略了许多细节,所以不同之处就在JMS规范之外的这些内容,很多也是非常重要的。总的来说,MQSeries的功能和性能方面明显占优,而WebLogic JMS的某些JMS配置更加简单易行。
在本文中,我尽量试图从客观的角度分析两种产品的差异,如有不妥之处,请读者不吝赐教。
1. 产品体系架构不同造成的差异
WebLogic JMS是一个纯Java实现的支持C-S架构的实现JMS规范的服务器产品;而MQSeries是使用本地语言(比如在UNIX和Windows上的C语言)编写的既支持C-S架构,又支持对等访问的实现完备MOM(包括JMS规范)的产品。 于是就产生出以下的不同点:
1.1 MQSeries支持真正的异步数据传输;而WebLogic JMS不支持。
异步发送数据到远端的消息服务器,是MQSeries等完备的MOM的特色。JMS规范规定了一个C-S架构,定义了JMS客户机与JMS服务器的开发接口,并没有定义JMS服务器与JMS服务器的规范,而客户机方面没有任何队列,所以只能说是规范了消息的存取,而没有规范消息数据的传输。因为JMS客户机并不拥有存放数据的队列,所以所有发送的操作都要由应用程序来控制,JMS服务器本身并不代理传输,也不保证数据在远程队列间传输的可靠性。WebLogic JMS就是这样的体系。
这种体系结构有时候是不能直接满足应用的要求的。首先,为了充分利用资源和提高效率,许多应用需要采用异步消息的机制。其次,许多需要快速返回的应用也必须使用异步传输。比如电话自动语音应答(IVR)的程序,某个操作需要把数据传输到远程的服务器上,但是必须立即返回,接受客户的下一个按键。
MQSeries通过通道与传输队列和远程队列来完成这一任务。能充分利用网络的带宽,甚至支持断网续传,保证数据传输的可靠性。当然,虽然应用程序不必作任何工作,但配置方面确实还要多学一些概念。
1.2 MQSeries支持多种语言的开发;而WebLogic JMS基本上只支持JAVA
MQSeries支持的语言包括C, C++, COBOL, JAVA, PL/1, REXX, RPG, Visual Basic (使用COM/ActiveX)等。老板本的MQSeries支持JAVA是通过一个叫MA88的SupportPac来实现,虽然经过广泛的使用和验证,但给人的感觉是不太方便。好在从5.3版起(目前最新的是6.0版),JAVA支持已经内置在MQSeries中。
WebLogic JMS一般只支持JAVA开发。但BEA也在dev2dev.bea.com网站上提供了一套免费的C的支持,称作“JMS C API”。参见http://dev2dev.bea.com/utilitiestools/environment.html?highlight=utilitiestools。但这个工具与老的MA88也是不能相提并论的,因为BEA并不真正支持它,因此也基本没有什么用户。参见BEA网站上关于“JMS C API”的警告:
|
1.3 纯JAVA实现的利与弊
MQSeries是用本地语言实现的,因此带来的好处是高性能和高并发的支持能力。MQSeries相对WebLogic JMS等产品的性能优势是非常明显的,所以MQSeries非常适于企业级的大数据量和高并发的数据传输业务。谁也无法想象一个企业级的数据应用会采用一个纯Java实现的数据库,因为其性能无法满足要求,对较大的数据传输应用也是一样的,纯Java实现的JMS服务器例如WebLogic JMS无法满足其性能的要求。
纯JAVA实现的JMS服务器也有其好处,就是与其它的J2EE服务完美地集成在一起。所以WebLogic的JMS配置显得更简洁。WebSphere+MQSeries也配合得很好,但总是能感觉到是这两个产品。WebLogic JMS的对象体系完全符合JMS的概念体系。而MQSeries要通过WebSphere Application Server或者一个叫JMSAdmin的工具,借助于目录服务来完成MQSeries概念体系到JMS概念体系的映射。应该是看到了这件事造成的麻烦,所以IBM在WebSphere v6也提供了一套纯JAVA实现的、与MQSeries可以互操作的JMS服务器。另外一点是WebLogic不需要WebSphere以及MQSeries那样的冗长的CLASSPATH等环境变量的设置,这点对开发人员有吸引力。
1.4 MQSeries的通信功能更加强大,WebLogic JMS也有自己的一些特色
JMS对通信功能的要求很少,所以对二者对通信支持能力还是有很大的差别的。总的来说,历史更悠久的MQSeries占优,但WebLogic JMS也有自己的特色。
- MQSeries支持支持真正的远程异步数据传输,甚至支持消息的路由,可以“多级跳”;WebLogic JMS不支持。
- MQSeries支持消息的分组和分段传输,对于大消息传输和不稳定的网络非常有意义。WebLogic JMS没有这方面的功能。
- 二者都支持SSL、持久性、优先级、超时等功能。除了完备的SSL实现之外,MQSeries的安全体系遭到了一些批评,使用通道的安全出口程序显得很麻烦,而使用用户名称但无须口令保护的远程数据通信,如何能令人满意?但在这一点上WebLogic JMS也很难说就好一些,因为WebLogic JMS仅仅支持C-S的操作,系统本身并不支持远程的数据传输(需要应用实现)。
- WebLogic JMS支持IP多播会话,能显著地提高局域网内广播通信的性能,但这种方式不保证数据接收的可靠性,只适于某些特定的应用。MQSeries本身不提供此功能,但在Event Broker和Message Broker等MQSeries的升级产品中提供IP多播的支持。
1.5 MQSeries的管理功能更加强大
JMS对管理功能的要求很少,在这方面MQSeries也有比较明显的优势。
- JMS对事务处理的支持包括的对XASession和XAConnection实现,这一点对MQSeries和WebLogic JMS是相同的。MQSeries本身还可以作为事务管理器,协调两阶段提交。
- MQSeries和WebLogic JMS都支持Message Driven Bean作为触发新的应用的一种方式。WebLogic JMS还支持一种称作Session Pool的类似的触发机制。但这类触发机制过于简化,也就是每个消息都触发一个新的线程的应用。MQSeries的触发机制更丰富,不但包括这种被称作Every的方式,还包括First和Depth等方式。另外MQSeries还可以触发各种执行程序或者MQSeries的通道。
- MQSeries拥有一套完备的日志系统,可以进行独立的系统备份和恢复,因此适于高规格的数据/消息传输的应用。WebLogic JMS没有这方面的支持。
2. 产品历史的不同造成的差异
MQSeries是个历史悠久的产品,而WebLogic JMS是个新兵,因此会有以下的差异:
2.1 MQSeries支持更多的系统平台
支持30多种系统平台。当然值得注意的是某些平台的MQSeries是由合作伙伴实现的。
WebLogic JMS是个新产品,支持的平台数与WebLogic Server一样,只有常用的几个。有人说所有支持JDK的平台都能跑WebLogic JMS的客户机,这是不正确的说法。因为JMS是J2EE规范的一种,J2SE的SDK并不包括JMS的支持,更不要说支持WebLogic的J2EE了。
2.2 MQSeries支持更多的通信协议
MQSeries支持很多通信协议,但目前在实践中常用的是TCP/IP协议和SNA协议。
WebLogic JMS仅支持TCP/IP协议。
有些人对MQSeries的单向通道的概念提出了异议,认为增加了配置的复杂性,仅仅是SNA协议的需要,而不是TCP/IP协议的需要。我个人认为这点也不无一些道理。但是在有防火墙的TCP/IP网络上,不同的方向还是有差异的。
3. 群集实现的差异
MQSeries与WebLogic JMS在支持群集时,差异比较大,应该说各有各的特点。
- MQSeries的群集建立在配置库和群集通道基础之上,可以定义“共享队列”;WebLogic JMS的群集建立在WebLogic群集基础之上,可以定义“分布式队列”。
- MQSeries在写共享队列时,如果发现本地有,就只写本地的队列(这称作本地优先);如果本地没有,就会轮流写到所有定义了此共享队列的队列管理器。MQSeries在读共享队列时,只能从本地取。WebLogic JMS在读写分布式队列时,不受本地影响,总是进行轮流或权重选择。听起来似乎WebLogic JMS的群集更灵活,其实也不尽然。当取得了JMS的对象QueueSender或QueueReceiver后,WebLogic实际上已经绑定了一个JMS服务器的实例。如果每次写或读一个消息,都重新生成QueueSender或QueueReceiver,虽然比较好地支持了负载均衡,但势必造成很大的性能损失。而MQSeries在轮流写共享队列时,没有这方面的问题。
- WebLogic JMS的分布式队列有一个叫做Forward Delay的有意思的属性,定义了一个时间的长度。系统一旦发现超过这个时间长度,还没有人读这个队列,就把它的消息转送给群集中有消费者的队列。有了这个属性,应用程序就可以只从一个JMS服务器的实例读消息了。