与Tomcat的IBM MQSeries连接池

sal*_*uar 4 java tomcat ibm-mq

我们正在尝试建立一个从tomcat到IBM MQSeries的jms连接,并考虑建立连接池。

我们点击了下面的链接,并提出了建议的解决方案:

Tomcat的WebSphere MQ连接池

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

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

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

我还与您分享了这两个文件context.xml(数据源和services.xml(Spring服务文件))

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="********" />
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

最好的祝福。

Jos*_*hMc 5

摘要

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

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

Product        Version  Release      End of Service
============   =======  ==========   =================
Websphere MQ   6.0      2005-06-24   2012-09-30
Run Code Online (Sandbox Code Playgroud)

评论的背景信息

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

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)
Run Code Online (Sandbox Code Playgroud)

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


您指向的另一个StackOveflow问题“ 使用Tomcat进行WebSphere MQ连接池 ”是指以下事实:v7.0之前的IBM MQ(例如v6.0)提供了连接池,但是在MQ v7.0上已将其删除,并且在问如何在v7.0及更高版本上获得类似功能。


如《WebSphere MQ使用Java版本6.0》手册的第504页所述,v6连接池是MQ v6.0 JMS中的缺省连接池:

setUseConnectionPooling

public void setUseConnectionPooling(boolean usePooling);

选择是否使用连接池。如果将其设置为true,则JMS将在通过ConnectionFactory创建的任何连接的生存期内启用连接池。这也会影响将usePooling设置为false所创建的连接。要在整个JVM中禁用连接池,请确保JVM中使用的所有ConnectionFactories的usePooling都设置为false。


实际上,在IBM MQ v8.0知识中心页面上记录了在MQ v7中删除了连接池的事实,这是“ 开发应用程序”>“开发JMS和Java平台,企业版应用程序”>“为JMS使用IBM MQ类”>“为JMS使用IBM MQ类>>类MQConnectionFactory

setUseConnectionPooling

public void setUseConnectionPooling(boolean usePooling)

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


为了解释您今天看到的行为,您还需要了解MQ v7.0中添加的MQ客户端通道共享对话行为,您可以在IBM MQ v8.0知识中心页面“ 迁移和升级”>“简介”中阅读有关此内容的信息。IBM MQ迁移>共存,兼容性和互操作性> MQI客户机:客户机连接和服务器连接通道的缺省行为。在下面引用一些细节:

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

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

SHARECNV(0)

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


放在一起,您将拥有一个具有以下设置的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知识中心页面开发应用程序>开发JMS和Java平台,企业版应用程序>使用JMS的IBM MQ类>编写IBM JMS应用程序的MQ类>访问IBM MQ功能>在JMS的IBM MQ类中共享TCP / IP连接

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

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


我建议您获得要用于Java版本的当前IBM MQ类,这样一来,您最多可以进行90个共享对话。如果争用是一个问题,则需要让MQ管理员增大MAXINST/ MAXINSTC设置并减小SHARECNV

对于JMS的IBM MQ类,您可以在IBM MQ v9知识中心页面“ 为JMS的IBM MQ类安装了什么 ”上找到所需的文件列表:

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

  • com.ibm.mq.allclient.jar
  • com.ibm.mq.traceControl.jar
  • jms.jar
  • fscontext.jar
  • providerutil.jar
  • 有弹性的城堡安全提供程序和CMS支持jar

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

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

请注意,只有com.ibm.mq.allclient.jarjms.jar和充气城堡的安全提供者和CMS支持jar文件都包含在可再发行组件的客户端,但都包含在Java中的所有客户端。您也正在运行9.0.0.0,建议您转到9.0.0.5。您可以在Fix Central上找到Redistributable和Java All客户端。