2013-01-17 60 views
1

客户使用此模式:Spring MDP:轮询间隔?

  • Apache的骆驼和CXF JMS接收器
  • 这些内部使用Spring的MDP(消息驱动的POJO)来实现他们的信息接收器
  • 他们被部署在IBM WebSphere Application Server上7
  • 队列管理器是IBM Websphere MQ 6
  • Spring MDP使用JNDI队列连接工厂绑定到队列管理器 - 支持连接池和会话池

这里是,这个人是使用骆驼这样的消息接收器的一个示例:

<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

你的JMS配置似乎罚款。那里没有任何东西会妨碍听众作为听众。你可以发布你的骆驼路线/配置吗? –

+0

在这条路线上会发现什么问题?重新:“没有任何东西会阻止听众作为听众。” - 会知道我在哪里可以找到有关MDP“侦听器”内部的文档。我担心,因为(可能是错误的)在线程中的答案:http://stackoverflow.com/questions/7390286/whats-the-difference-between-activationspec-and-connectionfactory。这表明MDP监听器在QCF上的行为是轮询的 - 与MDB相比,可能不是真正的异步监听器。我希望轮询应用不断地请求MGET。 –

+0

稍后的一些研究,阅读我的答案。不是100%肯定的,但它至少可以开始寻找。 –

回答

2

我不知道CXF,但骆驼听众:

好像在JmsConfiguration默认JMS消费的类型是“违约”。 这意味着,它将实现Spring的DefaultMessageListenerContainer。

Javadoc

使用纯JMS客户端API消息监听器容器的变体,特别是MessageConsumer.receive的环()调用

接收调用将映射到MQ GET呼叫。

还有一个选项可以指定一个Simple类型的消费者,我猜是你想要的。

使用普通JMS客户端API的MessageConsumer.setMessageListener()

消息侦听我不知道这里,但春节文档表明,简单的消息侦听器不支持XA事务。这可能是需要考虑的事情,因为您正在应用程序服务器中运行。

0

我们也有类似的问题,我们的大型机问:IBM大型机问:

注意,应用程序ID作为默认的用户身份 要传递给队列管理器。如果应用程序是在客户端传输模式下运行的 ,则该进程ID必须与 存在于服务器计算机上的相关授权一起存在。如果需要不同的身份,则应用程序应使用 createConnection(用户名,密码)方法。

或者换句话说,IBM使用JVM进程ID登录到MQ,除非我们在适当的凭据发送。我们在使用Spring,所以每次我们的DefaultMessageListenerContainer轮询Q时,都必须使用它发送凭证。我迷上了这些宝宝之一和巴姆,像一个魅力工作:

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> 
+0

这很有道理。我们也在反对大型机MQ。但是我们正在使用WebSphere JNDI队列连接工厂,而不是缓存连接工厂。我们还使用UserCredentialsConnectionFactoryAdapter传递凭证(请参阅上面的配置)。你有没有类似的特征,或者你是否直接将MQ连接到队列管理器? –

+0

我们使用的是Tomcat,所以我们在图片中没有Websphere。但是,我们仍在使用IBM MQQueueConnectionFactoryFactory来连接JNDI。很多jar问题,但他们解决了...... – markthegrea

+0

好的 - 你像我们一样使用UserCredentialsConnectionFactoryAdapter吗?我期望这个适配器与您的代码相似(创建连接时传递凭据)。另外,您的JNDI连接工厂是否支持应用服务器管理的连接池?我假设你没有在Spring应用程序中使用缓存连接工厂。 –