JMS传输与MQ传输的区别

15

我正在使用Oracle Service Bus(OSB)作为MOM,并且目标URI是IBM MQ队列。我只想知道哪种传输方式更好。OSB为此提供了两个适配器,JMS适配器和MQ适配器。有人知道它们的优缺点吗?TIA

6个回答

8
通常情况下,通过本地MQI接口发送消息会比使用JMS更快。但实际上,除非您每天发送大量消息,否则我怀疑您是否会看到真正的区别。然而,除了速度之外,还有其他需要考虑的因素。例如,如果您不熟悉MQI应用程序,则学习曲线将比JMS陡峭。
当通过MQ发送到另一个JMS目的地时,JMS头信息将映射到MQRFH2头。包含MQRFH2头是由您创建的Destination对象驱动的。如果目标是JMS端点,则包括头文件。
我在下面包含了一个链接,解释了如何映射字段:
1.将JMS消息映射到MQI消息。 实际上,除非您每天发送数百万条消息,否则我认为WebsphereMQ上的JMS性能将足以满足您的需求。至于请求回复中的线程阻塞,我认为您不需要担心。默认情况下,WebsphereMQ中的回复是由单独的线程消耗的,而不是请求线程。

是的,gwhitake,我正在处理一个非常高容量的应用程序,消息数量绝对偏高。 - hakish
我认为分段或其他标题以及一些安全设置等功能也需要MQI接口。 - eckes

5

我想补充一下我发现对我有用的方法。当您创建队列实例时,必须执行以下操作。

Queue queue = queueSession.createQueue("queue:///" + queueName + "?targetClient=1");
//Send w/o MQRFH2 header (i.e. receiver is not a JMS client but just MQ)

包含"?targetClient=1"将导致原始消息被发送而无需头部信息。
希望这能帮助某些人。Mark

3

性能不是将无JMS头信息的普通消息(MQ格式)从JMS客户端发送到MQ服务器的唯一原因。也可能是消息消费者是非JMS客户端,如Tivoli Workload Scheduler(TWS)和 .net。

我提供了一个解决方案,适用于Java独立客户端和JBoss,它们会从JMS消息中删除MQRFH2格式并将其转换为普通消息:

独立JMS客户端

import com.ibm.msg.client.wmq.WMQConstants;
import com.ibm.mq.jms.MQQueue;

Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://...);

InitialContext context = new InitialContext(env);

ConnectionFactory connectionFactory = (ConnectionFactory)   context.lookup(JNDI_QUEUE_CONNECTION_FACTORY);

//the following to extra lines make sure that you send 'MQ' messages
MQQueue mqQueue = (MQQueue) iniCtx.lookup(queueJNDI);
mqQueue.setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ);

Destination destination = (Destination) mqQueue;
...proceed as usual...

应用服务器 JBoss 7 资源适配器

<subsystem xmlns="urn:jboss:domain:resource-adapters:1.0">
<resource-adapters>
<resource-adapter>
    <archive>wmq.jmsra.rar</archive>
    <transaction-support>NoTransaction</transaction-support>
    <connection-definitions>
        <connection-definition class-name="com.ibm.mq.connector.outbound.ManagedConnectionFactoryImpl" jndi-name="java:jboss/jms/MqConnectionFactory" pool-name="MqConnectionFactoryPool">
            <config-property name="connectionNameList">${mqserver}</config-property>
            <config-property name="channel">${mqchannel}</config-property>
        </connection-definition>
    </connection-definitions>
    <admin-objects>
        <admin-object class-name="com.ibm.mq.connector.outbound.MQQueueProxy" jndi-name="java:jboss/jms/MyQueue" pool-name="MyQueuePool">
        <config-property name="baseQueueName">${queuename}</config-property>
        <config-property name="targetClient">MQ</config-property>
    </admin-object>
 </admin-objects>


3

这取决于MQ队列另一端的程序是否期望接收JMS或“本地”MQ消息。

MQ可以作为本地队列机制或JMS消息的传输方式。区别在于,JMS消息在消息缓冲区的开头具有一些标准头字段,而“本地”MQ消息仅包含您的程序发送到缓冲区的数据。


另一端的应用程序只关心消息正文,不对头字段进行任何操作。 - hakish
这并不完全正确。本地MQI消息也包含头信息。通常应用程序使用的仅是MQRFH2(Jms头),但您可以与其他头信息进行交互。 - gregwhitaker
@gwhitake. -- 但是本地MQ头文件在不同的结构中,而JMS头文件与消息一起传递在同一个缓冲区中。 - James Anderson

0

对于其他可能在这里寻找答案的人,我想提供一些更新的信息(截至2017年):

  • 本地MQ库从8.0版本开始处于“稳定”状态,因此在即将推出的版本中不会添加新功能,只会进行错误/安全性修复。例如,他们声称非JMS库中不支持异步消费和自动重新连接。

更多信息请参见API选择

自v8以来的一般声明是,新应用程序应使用IBM MQ类进行JMS。当然,这并不否定selotape提到的所有优缺点。您仍然需要进行一些配置,并且开箱即用的性能可能较差。实际上,v8有一个MP0E文档声称他们已经比较了Java JMS MQ应用程序和C++ MQI应用程序,前者在不同场景下慢了高达35%(所以如果您得到50与900,那么您做错了什么)。


IBM关于稳定性的声明并不适用于所有本地MQ库,它仅适用于Java的IBM MQ类。例如,C/C++ MQI不受此公告的影响。请参阅IBM MQ v9知识中心页面“Deprecated, stabilized and removed features”以获取更多信息。 "IBM将不会进一步增强IBM MQ Java类,并且它们在IBM MQ Version 8.0中发布的水平上已经获得功能稳定。" - JoshMc

0

从丰富的个人经验出发,我强烈推荐如有可能使用本地 MQ

JMS 传输缺点(使用 WMQ 时)-

  1. JMS 中的消息速率较慢(我进行了测量!)
  2. 使用 ".bindings" 文件(充当 JNDI 服务器)很麻烦,因为只能使用 WMQ Explorer(或可怕的 JMSAdmin cmd 工具)进行编辑
  3. 需要对 WMQ 和 Weblogic 有深入的了解
  4. 每次更改配置都需要重启 OSB 域

JMS 传输唯一的优点是支持 XA 事务。在 OSB 11.1.1.7 中已经解决了这个问题,现在两种传输方式都支持 XA。

本地 MQ 优点 -

  1. 速度更快
  2. OSB 直接访问 MQ Headers(非常好!)
  3. 可以在运行时配置本地 MQ 传输(使用 sbconsole)
  4. 轻松管理连接池

再次强烈建议尽可能使用 本地 MQ 传输在 OSB 中。


此外,“JMS头部在MQ上”的问题也会增加混淆和错误的可能性(我已经有过这样的经历)。 - selotape

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接