首页 > 解决方案 > ActiveMQ CMS:在创建消费者和设置监听器之间会丢失消息吗?

问题描述

使用侦听器设置 CMS 消费者涉及两个单独的调用:首先,获取消费者:

 cms::MessageConsumer* cms::Session::createConsumer( const cms::Destination* );

然后,在消费者上设置一个监听器:

void cms::MessageConsumer::setMessageListener( cms::MessageListener* );

如果实现在侦听器被激活之前订阅目的地(并从代理/路由器接收消息),消息是否会丢失?或者这些消息是否在内部排队并在激活时传递给侦听器?

为什么没有 API 调用以侦听器作为构造参数来创建使用者?(是因为 JMS 规范没有吗?)

(附录:这可能是 API 本身的一个缺陷。更合乎逻辑的顺序是从会话中实例化消费者,并cms::Consumer::subscribe( cms::Destination*, cms::MessageListener* )在 API 中有一个方法。)

标签: activemqactivemq-cpp

解决方案


我认为 API 不一定有缺陷。显然它可以设计成不同的方式,但我相信你所谓的问题的解决方案来自对象start上的方法Connection(通过继承Startable)。状态的文档Connection

CMS 客户端通常会创建一个连接、一个或多个会话以及多个消息生产者和消费者。创建连接时,它处于停止模式。这意味着没有消息被传递。

通常将连接保持在停止模式,直到设置完成(即,直到所有消息使用者都已创建)。此时,客户端调用连接的 start 方法,消息开始到达连接的消费者。当客户端仍在设置自身的过程中时,此设置约定最大限度地减少了异步消息传递可能导致的任何客户端混淆。

可以立即开始连接,之后可以进行设置。执行此操作的客户端必须准备好在仍处于设置过程中时处理异步消息传递。

这与 JMS 遵循的模式相同。

无论如何,无论您何时调用start(). 如果消费者使用自动确认模式,则只有在通过其中一种接收方法同步传递或通过侦听器异步传递消息后,才应自动确认消息onMessage。否则将是我估计的错误。在过去的 10 年里,我一直在使用 JMS 进行各种实现,我从未见过任何与此相关的消息丢失的情况。

如果你想在你已经调用之后添加消费者,你start()当然可以stop()先调用,但我认为简单地动态添加它们没有任何问题。


推荐阅读