JMS 传输与 MQ 传输

Posted

技术标签:

【中文标题】JMS 传输与 MQ 传输【英文标题】:JMS transport v/s MQ transport 【发布时间】:2011-03-24 01:40:45 【问题描述】:

我使用 Oracle Service Bus(OSB) 作为 MOM,目标 URI 是一个 IBM MQ 队列。我只想知道哪个是首选的交通工具。 OSB 提供了 2 个相同的适配器,JMS 适配器和 MQ 适配器用于传输。有谁知道相同的优点和缺点是什么。 TIA

【问题讨论】:

【参考方案1】:

通常,通过本机 MQI 接口发送消息会比使用 JMS 更快。实际上,除非您每天发送大量消息,否则我怀疑您会看到真正的区别。但是,除了速度之外,还有其他事情需要考虑。例如,如果您不熟悉 MQI 应用程序,学习曲线将比 JMS 更陡峭。

当通过 MQ 发送到另一个 JMS 目标时,JMS 标头信息被映射到 MQRFH2 标头。包含 MQRFH2 标头是由您创建的 Destination 对象驱动的。如果目标是 JMS 端点,则包含标头。

我在下面提供了一个链接,该链接解释了字段的映射方式:

    Mapping JMS messages onto MQI messages.

实际上,除非您每天发送数百万条消息,否则我会假设 WebsphereMQ 上的 JMS 性能足以满足您的需求。就请求回复中的线程阻塞而言,我认为您无需担心这一点。默认情况下,WebsphereMQ 中的回复由单独的线程而不是请求线程使用。

【讨论】:

是的 gwhitake,它是我正在开发的一个非常大容量的应用程序,消息数量肯定偏高。 我认为分段或其他标题以及一些安全设置等功能也需要 MQI 接口。【参考方案2】:

只是想添加我发现对我有用的内容。创建 Queue 实例时,您必须执行以下操作。

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”会导致发送的原始消息没有标头。

希望这对某人有所帮助。标记

【讨论】:

【参考方案3】:

这取决于 MQ 队列另一端的程序是期待 JMS 还是“本机”MQ 消息。

MQ 可以充当本机队列机制或 JMS 消息的传输。不同之处在于 JMS 消息在消息缓冲区的开头有一些标准头字段,而“本机”mq 消息仅包含您的程序发送到缓冲区的数据。

【讨论】:

另一端的app只关心消息的Body,不处理header字段。 这不是真的。本机 MQI 消息还包含标头。通常,应用程序使用的唯一一个是 MQRFH2(Jms 标头),但您可以与其他人交互。 @gwhitake。 -- 但是本地 MQ 标头位于不同的结构中,而 JMS 标头与消息在同一缓冲区中传递。【参考方案4】:

性能并不是从 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>

【讨论】:

【参考方案5】:

根据丰富的个人经验,我强烈建议尽可能使用 Native MQ

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

    JMS 中的消息速率变慢(我已经测量过!) 使用“.bindings”文件(充当 JNDI 服务器)很麻烦,因为它只能使用 WMQ Explorer(或可怕的 JMSAdmin cmd 工具)进行编辑 它需要 WMQ 和 Weblogic 方面的高级知识 每次更改配置都需要重新启动 OSB 域

对原生 MQ 的唯一主要专业 JMS 传输是它对 XA 事务的支持。这已在 OSB 11.1.1.7 中解决,现在两种传输都支持 XA。​​

本地 MQ 专业人士 -

    更快 OSB 可以直接访问 MQ 标头(这很棒!) 可以在运行时配置本机 MQ 传输(使用 sbconsole) 轻松管理连接池

再次,我强烈建议尽可能在 OSB 中使用 Native MQ 传输。

【讨论】:

此外,整个“JMS 标头 over MQ”问题增加了混乱和错误空间(我经历过)。【参考方案6】:

只是我的 2c 给其他可能会看这里的人,截至 2017 年的一些更新视图:

原生 MQ 库自 8.0 版起处于“稳定”状态,因此在即将发布的版本中不会添加新功能,只会修复错误/安全性。例如,他们声称异步消费和自动重新连接在非 JMS 库中不可用。

更多信息在这里Choice of API

自 v8 以来的一般性声明是,新应用程序应使用 IBM MQ 类用于 JMS。这当然不会使 selotape 提到的所有优点和缺点无效。您仍然需要更多配置,并且开箱即用的性能可能会较差。实际上有一个 v8 的 MP0E 文档声称他们已经将 Java JMS MQ 应用程序与 C++ MQI 应用程序进行了比较,前者根据场景的不同而慢了 35%(所以如果你得到 50 对 900 你正在做出了点问题)

【讨论】:

IBM 关于稳定性的声明并不适用于所有 Native MQ 库,它专门针对 Java 的 IBM MQ 类。例如,C/C++ MQI 不受此公告的影响。有关更多信息,请参阅 IBM MQ v9 知识中心页面“Deprecated, stabilized and removed features”。 “IBM 不会对用于 Java 的 IBM MQ 类进行进一步增强,它们的功能已稳定在 IBM MQ 8.0 版中的水平。”

以上是关于JMS 传输与 MQ 传输的主要内容,如果未能解决你的问题,请参考以下文章

Mule JMS ActiveMQ 传输失败到故障转移

WSO2 ESB 5.0.0 配置 JMS 传输(ActiveMQ)- 队列消息生产与消费

WSO2 ESB 5.0.0 配置 JMS 传输(ActiveMQ)- 队列消息生产与消费

WSO2 ESB 5.0.0 配置 JMS 传输(ActiveMQ)- 队列消息生产与消费

MQ消息队列的JMS规范和AMQP协议的区别

关于JMS和MQ