Spring DefaultMessageListenerContainer和ActiveMQ

时间:2012-08-21 02:51:05

标签: spring activemq

我已将Spring DefaultMessageListenerContainer配置为消耗队列消息的ActiveMQ使用者。我们称之为" Test.Queue" 我将这些代码部署在4台不同的机器上,所有机器都配置到同一个ActiveMQ实例来处理来自同一个" Test.Queue"队列。

一旦所有4台机器启动并运行,我将最大消费者大小设置为20,我看到消费者数量与队列数相比为80(4 *最大消费者大小= 80)

当生成并发送到队列的消息变得很高时,一切都很好。

如果有1000条消息,并且在80个消费者中,让我们说其中一个被卡住了,它会冻结Active MQ以停止向其他消费者发送消息。

所有消息都永远停留在ActiveMQ中。

由于我有4台机器,最多有80名消费者,我不知道哪个消费者没有承认。

我停下来重新启动所有4台机器,当我停止那些卡住了坏消费者的机器时,消息再次开始流动。

我不知道如何配置DefaultMessageListenerContainer以放弃不良消费者并立即向ActiveMQ发出信号以开始发送消息。

我甚至可以在没有Spring的情况下创建场景,如下所示:

  1. 我制作了多达5000条消息,然后将它们发送到" Test.Queue"队列
  2. 我创建了2个消费者(消费者A,B)和一个消费者B onMessage()方法,我把线程睡了很长时间( Thread.sleep(Long.MAX_VALUE))具有类似于当前时间%13为0的条件然后将线程置于休眠状态。

  3. 这两位消费者。

  4. 去了Active MQ,发现队列有2个消费者。
  5. A和B都在处理消息
  6. 在某个时间点,消费者B的onMessage()被调用,并且当当前时间%13的条件为0时,它使线程处于休眠状态。
  7. 消费者B被卡住了,它无法向经纪人承认
  8. 我回到Active MQ Web控制台,仍然将消费者视为2,但没有消息出列。
  9. 现在我创建了另一个消费者C并将其运行以消费。
  10. 只有ActiveMQ中的消费者数量从2增加到3
  11. 但消费者C没有消费任何东西,因为经纪人发送任何消息都没有发送,因为它仍在等待消费者B承认它。
  12. 我还注意到消费者A没有消费任何东西
  13. 我去杀死消费者B,现在所有的消息都被消耗掉了。
  14. 让我们说A,B,C由Spring的DefaultMessageListenerContainer管理,如何调整Spring DefaultMessageListenerContainer以便在不能确认之后将该坏用户从池中(在我的情况下是消费者B)中删除对于X秒数,立即确认代理,以便代理不会永久保留消息。

    感谢您的时间。

    感谢我能解决这个问题。

1 个答案:

答案 0 :(得分:3)

这里有几个选项可供尝试......

  1. 将队列预取设置为0,以促进跨消费者的更好分发,并减少特定消费者的“卡住”消息。见http://activemq.apache.org/what-is-the-prefetch-limit-for.html

  2. 在连接上设置“?useKeepAlive = false& wireFormat.maxInactivityDuration = 20000”,以便在指定的非活动时间后使慢速消费者超时

  3. 再次设置队列策略“slowConsumerStrategy-> abortSlowConsumer”...以使缓慢的消费者超时

    <policyEntry ...
      ...
      <slowConsumerStrategy>
          <abortSlowConsumerStrategy />
      </slowConsumerStrategy>
      ...
    </policyEntry>