【问题标题】:DefaultMessageListenerContainer managed with JMX + ActiveMQ Multiple Consumers on a Single QueueDefaultMessageListenerContainer 使用 JMX + ActiveMQ 管理单个队列上的多个消费者
【发布时间】:2012-01-03 16:33:50
【问题描述】:

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

发送 1 000 000 条消息。在 500 000 条消息之后,您希望其余消息仅由一个 DefaultMessageListenerContainer 处理,但不要在另一个上调用 destroy 或 shutdown(因为您将来可能需要它 -并且必须使用 JMX 使其易于管理)。这些数字只是此处的示例,应忽略,可以替换为 - “经过一段时间,经过一些消息等”

这听起来很简单:在另一个 DefaultMessageListenerContainer 上调用 stop。错误,因为消息是以循环方式发送的,并且它们会向消费者注册。

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

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

到目前为止我的解决方案:因为Session.AUTO_ACKNOWLEDGE 消息在进入DefaultMessageListenerContainer 的MessageListener 中的onMessage 方法之前从队列中取出。在MessageListener 中实现SessionAwareMessageListener 并重新发送具有相同有效负载的消息的新副本。 但这看起来真的很脏——我希望我能以“JMS”式的方式做更多的事情。

【问题讨论】:

  • 好吧,我可以“取消注册”来自特定消费者的消息吗?

标签: java spring jms jmx


【解决方案1】:

我没有完全掌握这部分:“[消息] 向消费者注册”。您的意思是 ActiveMQ 决定将其发送到哪个侦听器?当您在 DMLC 上调用“停止”时究竟会发生什么?

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

【讨论】:

  • 事实上我忘了提到我也尝试过消息选择器——它不起作用。在 MDLC 上调用 stop() 会发生什么?这是一个示例:两个 DMLC 都已启动,并且每个内部的 onMessage 方法都输出有效负载。我在 中发送两条消息,一个 DMLC 中的输出是“1111”,另一个中的输出是“2222”。我停止一个 DMLC 并再发送两个,第一个输出是“3333”,第二个什么也没有。我开始第二个:输出是“4444”。希望这很清楚
  • @Eugene 你能解释一下吗,如我的回答的第一部分所示?
  • 似乎在内部,带有默认循环策略的 ActiveMQ 以某种方式将每条消息注册到特定的消费者并保持此顺序。您会看到当 JMS 中未指定队列的多个消费者时会发生什么。由供应商决定。我今天将在 Tibco EMS 上再次测试并发布结果
  • @Eugene 感谢您的解释。现在我认为你的问题被误导了:你应该在 ActiveMQ 和 not Spring DMLC 的上下文中问它。看来您已经为 DMLC 做了所有可以做的事情。
  • 真的谢谢你。是的,我知道,我只是认为这可能是与消费者的注册表,并且消息发生在 JMS 标头中的某处,您可以清理它......无论如何,谢谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-22
  • 2020-06-17
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多