我正在开发一个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会重用缓存的连接。从而获得更好的消息接收吞吐量。