RabbitMQ:在没有消费者连接时丢弃消息

RabbitMQ: dropping messages when no consumers are connected

我正在尝试在只有一个生产者和一个消费者的模型中设置 RabbitMQ,并且生产者发送的消息仅在消费者连接时才传递给消费者,但在消费者连接时丢弃不存在。

基本上我希望队列在没有消费者连接到它时丢弃它收到的所有消息。

另一个约束是队列必须在 RabbitMQ 服务器端声明,并且不能由消费者或生产者显式创建。

这可能吗?

我看过一些东西,但我似乎无法让它发挥作用:

  1. durable vs non-durable 不起作用,因为它仅在代理重新启动时有用。我需要相同的效果,但需要连接。
  2. 在队列上将 auto_delete 设置为 true 意味着我的客户端永远无法再次连接到该队列。
  3. x-message-ttlmax-length 使得即使有消费者连接也有可能丢失消息。
  4. 我看过主题交换器,但据我所知,这些只影响基于消息内容的交换器和队列之间的消息路由,并不能考虑是否队列已连接消费者。

我正在寻找的效果在断开连接时类似于 auto_delete,在连接时类似于 auto_create。 rabbitmq 中是否有一种机制可以让我这样做?

你不能直接做,但是有一个机制不难实现。

您必须启用事件交换插件。这是您的服务器应用程序可以连接并将接收 RabbitMQ 内部事件的交换。您会对 consumer.created 和 consumer.deleted 事件感兴趣。

收到这些事件后,您可以触发一个操作(创建或删除您需要的队列)。此处有更多信息:https://www.rabbitmq.com/event-exchange.html

希望对您有所帮助。

经过更多研究,我发现问题中关于 x-message-ttl 的假设之一是错误的。我忽略了 RabbitMQ 文档中的一句话:

Setting the TTL to 0 causes messages to be expired upon reaching a queue unless they can be delivered to a consumer immediately

https://www.rabbitmq.com/ttl.html

事实证明,最简单的解决方案是在我的队列中将 x-message-ttl 设置为 0

如果您的消费者被允许在 start/stop 期间在代理上动态绑定/取消绑定队列,那么应该可以通过这种方式实现(例如,队列是预先设置的,并且消费者在启动期间将队列绑定到交换器它想从)

接收消息