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 共享池
看起来也很有前途,但是为 JMS 正确实现它需要一些良好的 JMS 知识
我们的问题:
- 是否有可用于包装 MQQueueConnectionFactory 并将连接、 session 、生产者和消费者汇集在一起的 JMS 提供者?
- 有没有人成功实现了我们上面概述的替代解决方案之一?
最佳答案
正如 Umapathy 在选项 3 中提出的那样,我们现在选择了使用 Spring 的 CachingConnectionFactory 的方法,即使对于非 Spring 应用程序,它也能很好地工作。您需要做的就是将 Spring Jars 添加到类路径,并使用 CachingConnectionFactory 包装 MQQueueConnectionFactory。
我们选择创建我们自己的 Tomcat QueueConnectionFactoryFactory,它使我们能够完全保持原始应用程序代码不变,您只需将 Tomcat 配置文件(如上问题所示)中的原始 MQ 连接工厂替换为以下 XML 定义:
<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;
}
}
关于java - 与 Tomcat 的 WebSphere MQ 连接池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30761793/