我们正在尝试建立从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(数据源和services.xml(春季服务文件)
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>
最诚挚的问候。
答案 0 :(得分:5)
摘要
您需要升级到JMS的MQ类的更高版本,或者让您的MQ管理员增加MAXINST / MAXINSTC设置以允许更多通道实例。
请注意,您使用的版本自2012年以来就不再受支持,因此我建议升级。
Product Version Release End of Service
============ ======= ========== =================
Websphere MQ 6.0 2005-06-24 2012-09-30
评论的背景信息
根据您在注释中提供的信息,可以了解有关当前设置的以下信息:
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。
setUseConnectionPooling
public void setUseConnectionPooling(boolean usePooling)
已弃用。 JMS不再使用连接池。 应该使用App Server提供的功能来完成。设置使用 早期版本的WebSphere MQ类中的ConnectionPooling JMS。 保留此方法是为了与较旧的MQJMS兼容 应用程序,但是,因为此连接池功能具有 已从版本7中删除,设置此属性将没有 效果。
要解释今天看到的行为,还需要了解MQ v7.0中添加的MQ客户端通道共享对话行为,您可以在IBM MQ v8.0知识中心页面{{3 }}。在下面引用一些细节:
在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知识中心页面Migrating and upgrading>Introduction to IBM MQ migration>Coexistence, compatibility, and interoperability>MQI client: Default behavior of client-connection and server-connection channels:
JMS应用程序创建的每个JMS连接和JMS会话都会创建自己与队列管理器的对话。
在您的情况下,因为您正在为JMS使用MQ v6.0类,所以每个“会话”都是到队列管理器的MQ通道实例(TCP连接)。
我建议您为Java版本使用当前的IBM MQ类,这样一来,您最多可以进行90个共享对话。如果存在争用问题,则需要让MQ管理员增加MAXINST
/ MAXINSTC
设置并减少SHARECNV
。
对于 JMS的IBM MQ类,您可以在IBM MQ v9知识中心页面“ 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”中找到所需的文件列表:
可重定位的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.jar
,jms.jar
以及Bouncy Castle安全提供程序和CMS支持jar,而Java All客户端中都包含了所有这些。您也正在运行9.0.0.0,建议您转到9.0.0.5。您可以在What is installed for IBM MQ classes for JMS上找到Redistributable和Java All客户端。