DefaultMessageListenerContainer线程问题

时间:2014-12-29 15:45:44

标签: spring spring-jms

我正在使用Spring JMS 4.1。

自上一篇文章([{1}}与DefaultJmsListenerContainerFactory的使用)后,我一直在使用CachingConnectionFactory(设置CachingConnectionFactorycacheConsumers){ {1}}:

false

我现在正在尝试使用我以编程方式定义的侦听器类:

DefaultJmsListenerContainerFactory

它正在工作,因为我的监听器类很好地接收了消息,但是日志看起来很奇怪。在开始之后,即使队列中有多个等待,看起来只有一个线程正在处理消息:

<bean id="cachedConnectionFactory" 
          class="org.springframework.jms.connection.CachingConnectionFactory"
        p:targetConnectionFactory-ref="jmsConnectionFactory"
        p:cacheConsumers="false"
        p:sessionCacheSize="3" />
<bean id="jmsListenerContainerFactory"
          class="org.springframework.jms.config.DefaultJmsListenerContainerFactory"
          p:connectionFactory-ref="cachedConnectionFactory"
          p:destinationResolver-ref="jndiDestinationResolver"
          p:concurrency="3-5"
          p:backOff-ref="exponentialBackOff"
          p:receiveTimeout="1000" />

正如您所看到的,最终只有容器#5用于处理所有剩余的消息。消息不是并行处理的,似乎没有使用定义的并发性。 我不知道它是否是完全相同的问题,但我看了一下这个post,但我没有使用ActiveMQ而且我没有这个预取选项。

你能解释一下为什么我有这种行为。是Spring配置错误还是其他地方的问题?

谢谢

编辑:最终我在消息代理上找到了一个选项,不保持消息顺序,事情变得越来越好。有一个更好的线程使用... 不过我可以看到:

  • 首先,使用5个public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) { ... MyListener receiver = new MyListener(); ... MessageListenerAdapter adapter = new MessageListenerAdapter(listener); adapter.setDefaultListenerMethod("onMessage"); ... SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint(); endpoint.setId(endpointId); endpoint.setDestination(...); endpoint.setMessageListener(adapter); registrar.registerEndpoint(endpoint); } 个线程(并发中的最大值);
  • 当剩余大约25条消息时,只有3条(并发核心值)正在处理消息;
  • 最终只有一个正在处理其余15条消息......

为什么在队列完全清空之前几乎不使用最大线程数(5)或至少核心数(即3)?

1 个答案:

答案 0 :(得分:1)

尽管很久以前就问过这个问题。我最近也面临这个问题。发布答案以造福他人。

需要将prefetch的限制设置为1。 您可以在连接字符串中提供它。

tcp://localhost:61616?jms.prefetchPolicy.queuePrefetch=1

参考 http://activemq.apache.org/what-is-the-prefetch-limit-for.html