ActiveMQ CMS:在创建消费者和设置监听器之间是否会丢失消息?

ActiveMQ CMS: Can messages be lost between creating a consumer and setting a listener?

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

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

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

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

如果实现在侦听器激活之前订阅目标(并从 broker/router 接收消息),消息是否会丢失?还是此类消息在内部排队并在激活时传递给侦听器?

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

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

我认为 API 不一定有缺陷。显然它可以设计成不同的方式,但我相信你所谓的问题的解决方案来自 start method on the Connection object (inherited via Startable)。 Connection 的文档指出:

A CMS client typically creates a connection, one or more sessions, and a number of message producers and consumers. When a connection is created, it is in stopped mode. That means that no messages are being delivered.

It is typical to leave the connection in stopped mode until setup is complete (that is, until all message consumers have been created). At that point, the client calls the connection's start method, and messages begin arriving at the connection's consumers. This setup convention minimizes any client confusion that may result from asynchronous message delivery while the client is still in the process of setting itself up.

A connection can be started immediately, and the setup can be done afterwards. Clients that do this must be prepared to handle asynchronous message delivery while they are still in the process of setting up.

这与 JMS 遵循的模式相同。

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

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