何时使用 RabbitMQ 声明/绑定队列和交换

Posted

技术标签:

【中文标题】何时使用 RabbitMQ 声明/绑定队列和交换【英文标题】:When to declare/bind Queues and Exchanges with RabbitMQ 【发布时间】:2016-05-28 11:45:02 【问题描述】:

在我的工作场所,我们有一个围绕 RabbitMQ 的包装库,由不再在这里工作的人创建。我正在使用 Rabbit 设计一个新系统,并且正在制定声明队列、交换和绑定的最佳方法。我们的 Rabbit 架构有几个联合的全局区域,每个区域都有多个 Rabbit 节点。

发布消息和订阅队列的包装代码每次都重新声明相关的交换、队列和绑定。我担心这可能会给每条消息发布带来很大的延迟,特别是如果它需要等待确认远程全局区域中存在队列/交换。我希望每秒数百万条消息的基准不会为每次发布重新声明交换。

简而言之,这种方法对我来说似乎有点浪费和偏执,但也许我错过了一些东西。

所以我有几个问题:

考虑到全球联合,重新声明队列和交换是否会对性能造成重大影响? 在每次使用时重新声明是否是一种好方法,因为它可以处理由于代理重新启动或显式删除而导致的队列/交换消失? 我们是否应该只为每个进程声明一次队列和交换 并期望它们能持续一生? 是否应该在 Rabbit 配置中声明持久交换和队列,而不是由应用程序声明? 如果应用程序可能继续使用旧配置声明队列/交换的配置更改,应如何处理?应用程序是否应该只处理声明失败并继续发布/消费?

【问题讨论】:

【参考方案1】:

重新声明队列和交换对性能有重大影响

它可以用于非常大量的消息

在每次使用时重新声明是否是一种好方法,因为它可以处理由于代理重启或显式删除而导致的队列/交换消失?

“好方法” - 不。

“有效”防止消失的交换/队列/绑定引起问题,是的……但在大多数情况下,这不是一件好事

(如果您只非常不频繁地发送消息,也许可以,确实有理由担心拓扑被擦除干净)

我们是否应该只为每个进程声明一次队列和交换,并期望它们持续整个生命周期?

这是我的一般方法。

它打开了拓扑被破坏而你不知道的可能性。这取决于你是否认为这真的会发生。

是否应该在 Rabbit 配置中声明持久交换和队列,而不是由应用程序声明?

预定义拓扑没有什么问题,但是它错过了rabbitmq和amqp协议的很多功能和灵活性。

许多消息传递系统需要预定义的拓扑和专门的工具来管理拓扑。 amqp 的不同之处在于它允许您根据需要定义拓扑。

如果您处理静态拓扑,那么这对您来说可能是一个不错的选择

如果应用程序可以继续使用旧配置声明队列/交换的配置更改,应如何处理它们?应用程序是否应该只处理声明失败并继续发布/消费?

我会让应用程序崩溃并通过您使用的任何错误报告机制进行报告。

进行拓扑更改通常很重要,并且是有原因的。如果交换或队列声明需要更改,可能是有充分理由的,代码不应继续使用旧声明。

【讨论】:

以上是关于何时使用 RabbitMQ 声明/绑定队列和交换的主要内容,如果未能解决你的问题,请参考以下文章

在哪里创建队列和交换?

RabbitMQ:交换、队列和绑定——谁来设置啥?

RabbitMQ学习总结

RabbitMQ 部分API解析

RabbitMQ的动态创建交换机、队列、绑定、死信队列,延迟队列代码实现

RabbitMQ 运转流程