Tomcat具有内置的JDBC连接池,但是不幸的是,没有内置的JMS连接池。
我们正在将旧版Tomcat Web应用程序从WebSphere MQ版本6迁移到7。不幸的是,连接池已在WebSphere MQ 7中删除,如下所述:http : //www-01.ibm.com/support/docview.wss?uid = swg21665128
现在我们担心,如果仅使用以下代码在Tomcat中配置MQ,就会遇到麻烦:
<Resource name="jms/XXXQCF" auth="Container" type="com.ibm.mq.jms.MQQueueConnectionFactory" factory="com.ibm.mq.jms.MQQueueConnectionFactoryFactory" description="JMS Queue Connection Factory" HOST="xxx.com" PORT="1429" CHAN="XXX" TRAN="1" QMGR="XXX" />
我们担心的原因是,在使用MQ 7时,它将不会使用池化JMS提供程序。有关详细信息,另请参见http://activemq.apache.org/jmstemplate- gotchas.html
我们看到的替代解决方案是:
1)使用Atomikos
Atomikos有一个com.atomikos.jms.AtomikosConnectionFactoryBean可以代替MQQueueConnectionFactory来使用,但是当我们不需要XA时,使用XA事务管理器会产生巨大的开销
2)使用Spring的CachingConnectionFactory
看起来是一个很好的解决方案,但不幸的是,我们的旧版应用程序未使用Spring。因此,我们假设使用CachingConnectionFactory会花费很多精力。
3)使用Apache Commons Pool
看起来也很有希望,但是正确地为JMS实施它需要一些JMS知识
我们的问题:
正如Umapathy在选项3中所建议的那样,我们现在选择了使用Spring的CachingConnectionFactory的方法,即使对于非Spring应用程序,它也能很好地工作。您需要做的就是将Spring Jars添加到类路径中,并用CachingConnectionFactory包装MQQueueConnectionFactory。
我们选择创建自己的Tomcat QueueConnectionFactoryFactory,使我们能够完全保持原始应用程序代码不变,您只需要使用以下XML定义替换Tomcat配置文件(问题中所示)中的原始MQ连接工厂:
<Resource name="jms/XXXQCF" auth="Container" type="org.springframework.jms.connection.CachingConnectionFactory" factory="at.rsf4j.core.utilities.RSFCachingMQQueueConnectionFactoryFactory" description="JMS Queue Connection Factory" HOST="xxx.com" PORT="1429" CHAN="XXX" TRAN="1" QMGR="XXX" />
这是RSFCachingMQQueueConnectionFactoryFactory的(简化)代码(无错误检查):
public class RSFCachingMQQueueConnectionFactoryFactory implements ObjectFactory{ public Object getObjectInstance (Object obj, Name name, Context nameCtx, Hashtable<?,?> environment) throws NamingException { Reference ref = (Reference) obj; String beanClassName = ref.getClassName(); Class<?> beanClass = Class.forName(beanClassName); if (CachingConnectionFactory.class.isAssignableFrom(beanClass)){ MQQueueConnectionFactoryFactory cff = new MQQueueConnectionFactoryFactory(); Reference mqReference = new Reference( MQQueueConnectionFactory.class.getName()); Enumeration<RefAddr> allAddrs = ref.getAll(); while (allAddrs.hasMoreElements()){ mqReference.add(allAddrs.nextElement()); } MQQueueConnectionFactory cf = (MQQueueConnectionFactory)cff.getObjectInstance(mqReference, name, nameCtx, environment); CachingConnectionFactory ccf = (CachingConnectionFactory)beanClass.newInstance(); ccf.setTargetConnectionFactory(cf); return ccf; } }