14.3. 优化客户端 JMS 性能

概述

两个主要设置会影响客户端的 JMS 性能:池和同步接收。

在客户端上,CXF 为每个消息创建一个新的 JMS 会话和 JMS producer。这是因为会话和制作者对象都是安全线程的。创建制作者特别要大量时间,因为它需要与服务器通信。

池连接工厂通过缓存连接、会话和制作者来提高性能。

对于 ActiveMQ,配置池很简单;例如:

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.pool.PooledConnectionFactory;

ConnectionFactory cf = new ActiveMQConnectionFactory("tcp://localhost:61616");
PooledConnectionFactory pcf = new PooledConnectionFactory();

//Set expiry timeout because the default (0) prevents reconnection on failure
pcf.setExpiryTimeout(5000);
pcf.setConnectionFactory(cf);

JMSConfiguration jmsConfig = new JMSConfiguration();

jmsConfig.setConnectionFactory(pdf);

有关池的更多信息,请参阅红帽 JBoss Fuse 事务指南中的"Appendix A 优化 JMS Single- 和 Multiple-Resource Transactions"的性能

避免同步接收

对于请求/回复交换,JMS 传输会发送请求,然后等待回复。尽可能使用 JMS MessageListener 异步实施请求/回复消息传递。

但是,当需要在端点间共享队列时,CXF 必须使用同步的 Consumer.receive() 方法。此场景需要 MessageListener 来使用消息选择器来过滤消息。消息选择器必须预先识别,因此 MessageListener 只打开一次。

应该避免预先知道消息选择器的两个情况:

  • JMSMessageID 用作 JMSCorrelationID

    如果 JMS 属性使用 ConduitIdSelectorconduitSelectorPrefix,则客户端不会设置 JMS 传输,则客户端不会设置 JMSCorrelationId。这会导致服务器使用请求消息的 JMSMessageId 作为 JMSCorrelationId。因为 JMSMessageID 无法预先识别,客户端必须使用 synchronous Consumer.receive() 方法。

    请注意,您必须在 IBM JMS 端点(默认)中使用 Consumer.receive() 方法。

  • 用户在请求消息中设置 JMStype,然后设置自定义 JMSCorrelationID

    同样,因为不能提前知道自定义 JMSCorrelationID,客户端必须使用 synchronous Consumer.receive() 方法。

因此,一般规则是避免使用需要同步接收的设置。