DefaultMessageListenerContainer使用单个队列上的JMX + ActiveMQ多个使用者进行管理

时间:2011-11-22 09:11:36

标签: java spring jms jmx

假设您有两个Spring DefaultMessageListenerContainer侦听同一个队列(例如ActiveMQ),在不同的VM中启动。

发送1 000 000条消息。在500 000条消息之后,您希望其余的消息只由一个DefaultMessageListenerContainer处理,但不要在另一方上调用destroy或shutdown(因为您可能需要它未来 - 并且必须使其与JMX保持一致)。这些数字只是在这里,应该被忽略,可以替换为 - “一段时间后,在一些消息之后等等”

这听起来很简单:在另一个DefaultMessageListenerContainer上停止呼叫。错了,因为消息是以循环方式发送的,并且它们已经在消费者处注册。

添加事务支持并在每次消息进入时在第二个DefaultMessageListenerContainer中抛出错误,它将被第一个回滚并被采用(循环)。错误的是,消息以某种方式向消费者注册,不允许第一个DefaultMessageListenerContainer接收消息。

即使您关闭/销毁第一个DMLC,该消息也不会被其他DMLC使用。只有当我杀死现在关闭/销毁的DMLC正在运行的JVM时才会消耗它们。

我的解决方案到目前为止:由于Session.AUTO_ACKNOWLEDGE消息在进入DefaultMessageListenerContainer的MessageListener中的onMessage方法之前从队列中取出。在MessageListener工具SessionAwareMessageListener中,使用相同的有效负载重新发送邮件的新副本。 但这看起来很脏 - 我希望我能以“JMS”方式做得更多。

1 个答案:

答案 0 :(得分:1)

我没有完全掌握这一部分:“[消息]在消费者处注册”。你的意思是ActiveMQ决定将哪个侦听器发送给它?当你在DMLC上叫“停止”时会发生什么?

我不知道这是否会克服您的困难,但这里有一个想法:DMLC中的信息选择器实时:您可以随时更改它们并立即生效。也许尝试将消息选择器更改为“FALSE”;所有缓存的消息都应该完成处理,新的消息应该停止。