java - 与 Tomcat 的 WebSphere MQ 连接池

标签 java tomcat ibm-mq

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/

相关文章:

java - 正则表达式在 Android 中不起作用,但在 Java 中运行良好

java - Tomcat "Connection Reset"SSL 错误

java - 如何在 Eclipse 中添加 Java 项目而不是 Jar

ibm-mq - WMQ的SVR Channel可以连接多个RQSTR channel 吗?

java - 需要帮助用 Java 解析文件

java - 我们可以使用 Exception 类处理 HttpRequestMethodNotSupportedException

tomcat - 打开 Worklight 应用程序中心时出错

java - 从 Java Web Start 运行 Tomcat

java - 在 JVM 集群中使用 JMS 的 IBM MQ 监听器

c# - 如何实现消息队列解决方案