客户使用此模式:
这是一个这样的消息接收器的例子,这个是使用Camel:
<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent">
<property name="configuration" ref="jmsConfig"/>
</bean>
<!-- JNDI reference to the queue manager -->
<jee:jndi-lookup id="myTargetConnectionFactory" jndi-name="${mq.queueconnectionfactory}"/>
<bean id="jmsDestResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver"/>
<bean id="myConnectionFactory" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="targetConnectionFactory" ref="myTargetConnectionFactory"/>
<property name="username" value="SOME_USER"/>
<property name="password" value=""/>
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="${mq.connectionfactorybean}" />
<property name="destinationResolver" ref="jmsDestResolver" />
<property name="concurrentConsumers" value="1" />
<property name="maxConcurrentConsumers" value="1" />
<!--
NOTE: If we try to use a cache without a transactionManager we get "Connection closed" errors
-->
<property name="cacheLevelName" value="CACHE_NONE" />
</bean>
问题: WebSphere MQ管理员正在针对队列管理器报告大量的MGET()请求。目前的假设是那些接收者不断地在频道上轮询新消息。
他们似乎没有MDB(消息驱动的bean)的这个问题。 MDP异步实现真的是一种轮询机制吗?如果是这样,有没有办法限制到队列管理器的行程?也许增加轮询间隔?任何见解都将不胜感激。
答案 0 :(得分:2)
我不确定CXF,但是对于Camel听众:
JmsConfiguration中的默认JMS使用者似乎是“默认”类型。 方法,它将实现Spring的DefaultMessageListenerContainer。
来自Javadoc
使用普通JMS客户端API的消息侦听器容器变体,特别是MessageConsumer.receive()调用的循环
接收呼叫将映射到MQ GET呼叫。
还可以选择指定Simple类型的消费者,我想这就是你想要的。
使用普通JMS客户端API的MessageConsumer.setMessageListener()
的消息侦听器容器
我不确定这里,但Spring文档表明简单的消息监听器容器不支持XA事务。这可能需要考虑,因为您在应用程序服务器中运行。
答案 1 :(得分:0)
我们的Mainframe Q遇到了类似的问题.IBM主机q:
请注意,应用程序进程ID用作默认用户 要传递给队列管理器的标识。如果申请是 在客户端传输模式下运行,然后此进程ID必须存在 服务器机器上的相关授权。如果不同 身份是必需的,那么应用程序应该使用 createConnection(用户名,密码)方法。
或者换句话说,IBM使用JVM进程ID登录mq,除非我们发送适当的凭据。我们使用的是Spring,因此每次我们的DefaultMessageListenerContainer都会轮询Q,它必须使用它发送凭据。我把这些婴儿和Bam中的一个联系起来,就像一个魅力:
public class CustomConnectionFactory extends CachingConnectionFactory {
private String username;
private String password;
...
/**
* This is the secret sauce. Each time when we make a connection, we send
* the username/password.
*/
protected Connection doCreateConnection() throws JMSException {
return getTargetConnectionFactory().createConnection(this.username, this.password);
}
我们的主机更快乐。我们后来切换到分布式MQ,一切都好多了!
以下是我们的最终设置:
<!-- This hooks us up to the jndi -->
<jee:jndi-lookup id="telematicsJNDIConnectionFactory" jndi-name="${mq.jndi}" cache="true" lookup-on-startup="true" />
<!-- The outer wrapper must be TransactionAware, the inner custom one will cache the connection -->
<bean id="telematicsConnectionFactory" class="org.springframework.jms.connection.TransactionAwareConnectionFactoryProxy">
<property name="targetConnectionFactory">
<bean class="cat.dds.tmatic.utils.CustomConnectionFactory">
<property name="targetConnectionFactory">
<ref bean="telematicsJNDIConnectionFactory" />
</property>
<property name="username">
<value>${mq.user}</value>
</property>
<property name="password">
<value>${mq.pass}</value>
</property>
<property name="sessionCacheSize">
<value>10</value>
</property>
</bean>
</property>
<property name="synchedLocalTransactionAllowed" value="true" />
</bean>