为什么Channel.waitForConfirmsOrDie阻塞?

时间:2012-10-30 04:09:17

标签: rabbitmq

我有一个发布 - 订阅用例,我希望在发布端阻止,直到每个订阅者确认他们已完成处理发布者发送的消息。

我(错误地?)假设我可以使用RabbitMQ及其Java amqp-client的Channel.waitForConfirmsOrDie方法作为我的解决方案的一部分。问题是我没有找到waitForConfirmsOrDie实际阻止的情况。

根据javadocs,waitForConfirmsOrDie应该:

  

等到自上次通话以来发布的所有消息都被代理人确认或解密。如果任何消息都没有,那么waitForConfirmsOrDie将抛出IOException。在非确认频道上呼叫时,它将立即返回。

为了测试这种方法是否真的有用,我从this example code from the RabbitMQ website开始。

示例代码创建一个发布者和一个使用者,每个都在自己独立的线程上。然后,当消费者使用消息时,发布者将消息发送到交换机。似乎发布者应该阻止,直到通过调用waitForConfirmsOrDie()来获取所有消息。

这个示例代码似乎与我尝试的完美匹配。但是,它似乎没有像我想象的那样工作。实际上,如果在消费者线程中,我关闭了自动执行消息,那么waitForConfirmsOrDie()仍会立即返回。

我通过将一个false更改为true来关闭auto ack: ch.queueDeclare(QUEUE_NAME, false, false, false, null);ch.queueDeclare(QUEUE_NAME, true, false, false, null);(第二个arg而不是true)。我相信这意味着消费者不应再发送消息。

那么waitForConfirmsOrDie()实际上做了什么?什么时候会阻止?

如果waitForConfirmsOrDie没有按我的意愿行事,是否有办法让发布商等到所有订阅者在继续之前收到消息?

1 个答案:

答案 0 :(得分:9)

据我了解,这些电话不应等待消费者的确认。 waitForConfirms*方法的目的是确保您的消息已发送到代理并提供基本的已发送/失败类型的通知。换句话说,如果rmq节点之一(或甚至所有节点)失败/不可用,则消息不会在没有通知产生的情况下消失。

如果您在basicPublish来电之前断开连接或关闭rmq,则可以看到此例外情况。