【问题标题】:IBM MQSeries connection pooling with Tomcat使用 Tomcat 的 IBM MQSeries 连接池
【发布时间】:2019-04-09 15:02:31
【问题描述】:

我们正在尝试建立从 tomcat 到 IBM MQSeries 的 jms 连接,以建立连接池。

我们已经按照下面的链接,给出了建议的解决方案:

WebSphere MQ connection pooling with Tomcat

我不知道我们如何使用建议的方法管理不同的jms连接,我们进行了测试,我们注意到CachingConnectionFactory管理不同的jms会话而不是jms连接。

我和你分享下面的链接,其中解释了 CachingConnectionFactory 不允许管理不同的 jms 连接,而只允许管理 jms 会话!

https://jira.spring.io/browse/SPR-13586

我也和大家分享一下,两个文件 context.xml(datasource 和 services.xml(spring services 文件)

context.xml

<Resource name="jms/AN8.NOTI.MOBILE.01" auth="Container" type="org.springframework.jms.connection.CachingConnectionFactory" 
    factory="com.cl.fwk.jms.utilities.RSFCachingMQQueueConnectionFactoryFactory" 
    description="JMS Queue Connection Factory for sending messages" HOST="**********" 
    PORT="****" CHAN="******" TRAN="*" QMGR="***" />

<Resource name="jms/MQAN8.NOTI.MOBILE.01" auth="Container"
    type="com.ibm.mq.jms.MQQueue" factory="com.ibm.mq.jms.MQQueueFactory"
    description="JMS Queue for receiving messages from Dialog" QU="********" />

services.xml

<!-- Ressource JNDI pour la connexion MQSeries-->
<bean id="xxxx.jmsRefConnectionFactory.mqseries" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jms/AN8.NOTI.MOBILE.01" />
    <property name="resourceRef" value="true" />
</bean>

<!-- Ressource JNDI pour la file d'attente du broker MQSeries-->
<bean id="xxxx.jmsRefQueue.mqseries" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jms/MQAN8.NOTI.MOBILE.01" />
    <property name="resourceRef" value="true" />
</bean>
<!-- A cached connection to wrap the MQSeries connection -->
<bean id="xxxx.jmsConnectionFactory.mqseries" class="org.springframework.jms.connection.CachingConnectionFactory">
    <!-- <constructor-arg ref="xxxx.jmsRefConnectionFactory.mqseries" /> -->
    <property name="targetConnectionFactory" ref="xxxx.jmsRefConnectionFactory.mqseries"/>
    <property name="sessionCacheSize" value="10" />
</bean>

<bean id="xxxx.jmsDestinationResolver.amq" class="org.springframework.jms.support.destination.DynamicDestinationResolver" />

<bean id="xxxx.jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="xxxx.jmsConnectionFactory.mqseries" />
    <property name="defaultDestination" ref="xxxx.jmsRefQueue.mqseries" />
    <property name="destinationResolver" ref="xxxx.jmsDestinationResolver.amq" />
    <property name="sessionTransacted" value="true" />
    <property name="sessionAcknowledgeMode" value="#{T(javax.jms.Session).AUTO_ACKNOWLEDGE}" />
</bean>

最好的问候。

【问题讨论】:

  • 不,在我的问题中,ActiveMq 和 IBM MQ 之间没有混合。 tomcat 有内置的 JDBC 连接池,但遗憾的是没有内置的 JMS 连接池。我们尝试
  • 你是对的,但只是写错了。我刚刚更正了豆子的名称。就像我说的,我希望能够管理池连接 jms。 CachingConnectionFactory 只能在后台维护 1 个 TCP 连接,我们希望在其下管理与多个会话/消费者/生产者的多个 TCP 连接,这对于高负载系统是必需的。
  • 我们使用的jar如下:mq-7.0.0.jar, mqjms-7.0.0.jar
  • 我们使用的jar如下:mq-7.0.0.jar, mqjms-7.0.0.jar
  • 会话对我有用,但我们受到一个 jms 连接的限制,这意味着我们受到 10 个会话的限制。我认为每个 jms 连接只提供 10 个会话。在 MANIFEST.MF 的内容下方 jar mq-7.0.0.jar 和 mqjms-7.0.0.jar : 实施-标题:Java 消息服务规范的 WebSphere MQ 类-供应商:Sun Microsystems, Inc. 规范-版本:1.1实施-版本:6.0.2.11 - j600-211-110318 规范-版本:6.0.2.11 实施-版本:6.0.2.11 - j600-211-110318

标签: java tomcat ibm-mq


【解决方案1】:

总结

您需要升级到更高版本的 JMS MQ 类,或者让您的 MQ 管理员增加 MAXINST/MAXINSTC 设置以允许更多通道实例。

请注意,您使用的版本自 2012 年以来已不受支持,因此我建议您升级。

Product        Version  Release      End of Service
============   =======  ==========   =================
Websphere MQ   6.0      2005-06-24   2012-09-30

评论的背景信息

根据您在 cmets 中提供的信息,您可以了解以下有关您当前设置的信息:

IBM MQ Server version: 8.0.0.? (specific maintenance level unknown)
IBM MQ jar names: mq-7.0.0.jar and mqjms-7.0.0.jar
IBM MQ jar version: 6.0.2.11
SVRCONN Channel settings: SHARECNV(10) MAXINST(9) MAXINSTC(9)

请注意,尽管 jar 文件的名称包含字符串 7.0.0,但它们实际上来自 IBM MQ v6.0.2.11(当时技术上称为 Websphere MQ)。


您指向的另一个 StackOveflow 问题“WebSphere MQ connection pooling with Tomcat”是指 v7.0 之前的 IBM MQ(例如 v6.0)提供了连接池,但在 MQ v7.0 中已将其删除,并且正在询问如何在 v7.0 及更高版本中获得类似的功能。


v6 连接池是 MQ v6.0 JMS 中的默认设置,如“WebSphere MQ Using Java Version 6.0”手册第 504 页所述:

setUseConnectionPooling

public void setUseConnectionPooling(boolean usePooling);

选择是否使用连接池。如果将此设置为 true, JMS 在任何连接的生命周期内启用连接池 通过 ConnectionFactory 创建。这也会影响连接 创建时将 usePooling 设置为 false;禁用连接池 在整个 JVM 中,确保在 JVM 已将 usePooling 设置为 false。


事实上,在 MQ v7 中删除了连接池这一事实记录在 IBM MQ v8.0 知识中心页面Developing applications>Developing JMS and Java Platform, Enterprise Edition applications>Using IBM MQ classes for JMS>IBM MQ classes for JMS>Class MQConnectionFactory

setUseConnectionPooling

public void setUseConnectionPooling(boolean usePooling)

已弃用。 JMS 不再使用连接池。 任何连接池 应该使用 App Server 提供的工具来完成。设置使用 早期版本的 WebSphere MQ 类中的 ConnectionPooling JMS。 保留此方法是为了与旧 MQJMS 兼容 应用程序,但是,因为此连接池功能具有 已从版本 7 中删除,设置此属性将没有 效果。


要解释您今天看到的行为,您还需要了解 MQ v7.0 中添加的 MQ 客户端通道共享对话行为,您可以在 IBM MQ v8.0 知识中心页面 Migrating and upgrading>Introduction to IBM MQ migration>Coexistence, compatibility, and interoperability>MQI client: Default behavior of client-connection and server-connection channels 中阅读相关内容.引用下面的一些细节:

在 7.0 版中,客户端和服务器连接的默认设置 频道更改为使用共享对话。这一变化影响 心跳和通道退出的行为,并可能对 性能。

在 7.0 版之前,每个对话都被分配到不同的 通道实例。从版本 7.0 开始,客户端和服务器的默认设置 连接是共享一个 MQI 通道。您使用 SHARECNV(共享 对话)参数来指定最大数量 可以通过特定 TCP/IP 客户端共享的对话 通道实例。可能的值如下:

SHARECNV(0)

  • 此值指定不通过 TCP/IP 套接字共享对话。通道实例的行为与版本完全相同 6.0服务器或客户端连接通道,并且您没有获得额外的功能,例如当您使用时可用的双向心跳 将 SHARECNV 设置为 1 或更大。如果您有,请仅使用值 0 设置时无法正确运行的现有客户端应用程序 SHARECNV 为 1 或更大。


综上所述,您有一个具有以下设置的 SVRCONN 频道:

  • SHARECNV(10)
  • MAXINST(9)
  • MAXINSTC(9)

当与 MQ v7.0 及更高版本的客户端一起使用时,这些设置意味着您可以在客户端和队列管理器之间有 9 个通道实例(TCP 连接),每个通道实例可以有 10 个共享会话,总共最多 90 个对话。

因为您使用的是用于 JMS 的 MQ v6.0 类,所以通道的运行方式就像设置为:

  • SHARECNV(0)
  • MAXINST(9)
  • MAXINSTC(9)

这意味着客户端和队列管理器之间可以有 9 个通道实例(TCP 连接),每个通道实例只支持一个对话。

在 JMS 的 MQ v6.0 类中,每个底层 JMS 连接和在 JMS 连接之上创建的每个 JMS 会话都将为队列管理器分配一个通道实例。


要了解有关连接和会话如何相互交互以及与 SHARECNV 设置交互的更多信息,请查看 IBM MQ v8.0 知识中心页面Developing applications>Developing JMS and Java Platform, Enterprise Edition applications>Using IBM MQ classes for JMS>Writing IBM MQ classes for JMS applications>Accessing IBM MQ features>Sharing a TCP/IP connection in IBM MQ classes for JMS

JMS 应用程序创建的每个 JMS 连接和 JMS 会话都会创建自己的与队列管理器的对话。

在您的情况下,因为您将 MQ v6.0 类用于 JMS,每个“对话”都是队列管理器的 MQ 通道实例(TCP 连接)。


我建议您使用当前的 IBM MQ 类 Java 版本,这样您就可以拥有多达 90 个共享对话。如果争用是一个问题,您需要让您的 MQ 管理员增加 MAXINST/MAXINSTC 设置并减少 SHARECNV

对于 IBM MQ Classes for JMS,您可以在 IBM MQ v9 知识中心页面“What is installed for IBM MQ classes for JMS”上找到所需的文件列表:

可重定位的 JAR 文件
在企业内部,可以将以下文件移动到需要为 JMS 运行 IBM MQ 类的系统中:

  • com.ibm.mq.allclient.jar
  • com.ibm.mq.traceControl.jar
  • jms.jar
  • fscontext.jar
  • providerutil.jar
  • Bouncy Castle 安全提供程序和 CMS 支持 jars

如果您的应用程序使用文件系统上下文执行 JNDI 查找,则需要 fscontext.jar 和 providerutil.jar 文件。

需要 Bouncy Castle 安全提供程序和 CMS 支持 jar 文件。有关更多信息,请参阅对非 IBM JRE 的支持。

请注意,只有 com.ibm.mq.allclient.jarjms.jar 和 Bouncy Castle 安全提供程序和 CMS 支持 jar 包含在 Redistributable 客户端中,但所有这些 jar 都包含在 Java All 客户端中。您也在运行 9.0.0.0,我建议您转到 9.0.0.5。您可以在 Fix Central 上找到 Redistributable 和 Java All 客户端。

【讨论】:

  • 感谢您的详细解释。我目前正在努力解决同样的问题。我有一个非常高性能的应用程序,我们目前正在使用 springs cachignconnetionfactory 以及正确的 MQ 设置,但仍然不够好。有没有办法实现连接池,以便应用程序与队列管理器等有多个连接?
  • 您能解释一下您要解决的问题吗?性能有问题吗?您是否达到队列管理器中的通道限制?
  • 所以,问题在于它是一个负载非常高的应用程序(每秒 1000 个请求),SLA 非常低。所以,这是一个性能问题。我们处于通道限制。所以想探索是否有一种方法可以实现连接池并在其中有并行连接,而不是使用带有缓存会话的单个连接。
  • 队列管理器运行的是什么版本的 mq 以及您的应用程序使用的 mq jar 文件的版本?
  • MQ 版本是 8,客户端 jar 是版本 9。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-26
  • 1970-01-01
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多