ActiveMQ CMS:在创建使用者和设置侦听器之间会丢失消息吗



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

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

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

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

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

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

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

我认为API不一定有缺陷。显然,它可以用不同的方式设计,但我相信您所声称的问题的解决方案来自Connection对象上的start方法(通过Startable继承(。Connection的文档说明:

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

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

可以立即启动连接,然后再进行设置。执行此操作的客户端必须准备好在设置过程中处理异步消息传递。

这与JMS遵循的模式相同。

在任何情况下,我认为无论何时调用start()都不会有消息丢失的风险。如果使用者使用的是自动确认模式,那么只有在消息通过其中一个接收方法同步传递或通过侦听器的onMessage异步传递后,才应自动确认消息。否则的话,我估计是个错误。在过去的10年里,我与JMS合作了各种实现,从未见过任何与此相关的消息丢失情况。

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

最新更新