Spring JMSTemplate with ibm.mq.jms.MQQueueConnectionFactory



我正在开发一个JMS密集型应用程序,它发送/接收数十万条消息。我发现性能不是那么好,并将问题缩小到如下一行,从我能看出的根本原因是它不能很好地与IBM MQ一起运行。

JMSTemplate.receive(queueName);

将这段代码封装在一个简单的计时器中后,我发现接收的时间在20-50毫秒之间,而且由于我正在处理的吞吐量的绝对数量,随着时间的推移,这肯定会增加。在google上搜索了一下之后,我偶然发现了spring"CachingConnectionFactory",我像下面这样幸运地实现了它(不确定它是否能与我已经在使用的IBM MQ Connection factory一起工作)。注意,为了便于阅读,省略了一些代码…

    <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        ...
    </bean>
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory">
            <ref bean="cacheFactory" />
        </property>
        ...
    </bean>
    <!--This seems to be the magic piece-->
    <bean id="cacheFactory"
        class="org.springframework.jms.connection.CachingConnectionFactory">
        <property name="targetConnectionFactory" ref="ibmMQConnectionFactory" />
        <property name="sessionCacheSize" value="100" />
    </bean>
    <bean id="ibmMQConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
        ...
    </bean>

令我惊讶的是,这将我的JMSTemplate.receive()调用从每条消息的20-50毫秒减少到大约1-2毫秒。我找不到任何可靠的信息,说明这在幕后是如何工作的,以及"sessionCacheSize"将如何影响性能。在第一次测试中,我使用的值是50,第二次使用的值是100,第二个选项证明要快得多。所以我的问题是,对于具有大量吞吐量的应用程序来说,理想的"sessionCacheSize"是多少?使用这种方法需要考虑哪些缺点?

我对Spring的了解有限。但是通过阅读您的描述,我相信Spring每次接收消息时都会执行以下操作:

1)创建到IBM MQ队列管理器的连接

2)打开指定队列

3)从队列获取消息

4)关闭队列 5)关闭连接。

由于上述所有操作,接收单个消息所需的时间更长。但是当session被缓存时,Spring会重用缓存的连接。从而获得更好的消息接收吞吐量。

最新更新