RabbitMQ更改生产系统上的队列参数

RabbitMQ更改生产系统上的队列参数,rabbitmq,pika,bunny,Rabbitmq,Pika,Bunny,我将RabbitMQ用作面向服务体系结构中的消息队列,其中许多单独的web服务发布绑定到RabbitMQ队列的消息。这些队列依次由执行后台工作的各种消费者订阅;RabbitMQ的一个非常普通的用例 现在,我想更改一些队列参数(特别是,我想将队列绑定到具有特定路由密钥的新死信交换)。我的问题是,在生产系统中进行这种更改是有问题的,原因有两个 对于我来说,在生产系统中转换到这些新队列而不丢失消息的最佳方式是什么 我已经考虑了从队列名称版本控制到使用新设置创建新vhost,再到进行所有更改的所有方面

我将RabbitMQ用作面向服务体系结构中的消息队列,其中许多单独的web服务发布绑定到RabbitMQ队列的消息。这些队列依次由执行后台工作的各种消费者订阅;RabbitMQ的一个非常普通的用例

现在,我想更改一些队列参数(特别是,我想将队列绑定到具有特定路由密钥的新死信交换)。我的问题是,在生产系统中进行这种更改是有问题的,原因有两个

对于我来说,在生产系统中转换到这些新队列而不丢失消息的最佳方式是什么

我已经考虑了从队列名称版本控制到使用新设置创建新vhost,再到进行所有更改的所有方面

以下是我面临的一些问题:

  • 因为RabbitMQ队列是幂等的,所以不同的web服务在发布到队列之前已经声明了队列(以防它们不存在)。更改队列参数(但保持相同的路由密钥)后,队列声明将失败,RabbitMQ将关闭通道

  • 我不希望在更改队列时丢失消息(这里我计划订阅一个独占消费者,它保存消息,然后重新发布到新队列)

  • 完全不同的发布者和消费者之间的一般协调(或者,更好的是,一种避免需要协调它们的方式)


  • 队列绑定可以在运行时添加和删除,而不会对客户端产生任何影响,除非客户端手动修改绑定。所以,如果您的问题只涉及绑定,只需通过CLI或web管理面板更改它们,并跳过下面的内容

    恢复不兼容的更改是一个常见问题,尤其是在异构环境中,尤其是当多个应用程序试图以自己的方式(使用其特定设置)声明同一实体时。在多个应用程序中,无法同时更改队列声明,这在很大程度上取决于整个工作流程的组织方式、应用程序的重要性、基础设施等

    又快又脏的方式:

    虽然发布者不处理队列声明和绑定(至少他们不应该这样做),但您可以关注消费者。在try-except块中包装队列声明可能是快速而肮脏的选择。此外,大多数项目(甚至很多项目)都可以在短暂的停机时间内生存下来,所以您可以在一个shell中阻止rabbitmq用户,根据您的意愿更改队列(创建新的队列,让您的用户使用它而不是旧的队列),然后取消阻止用户,让用户像以前一样工作(您的工作人员在主管或监控之下,对吗?)。然后手动将消息从旧队列迁移到新队列

    快速安全的解决方案:

    这是一个有点棘手的问题,它是基于如何在单个vhost中将消息从一个队列迁移到另一个队列的技术。整个解决方案在单个vhost中工作,但对于要修改的每个队列,都需要额外的队列。在源队列上设置,并将其指向将过期消息路由到新的目标队列。然后应用到源队列,设置
    x-message-ttl=0
    (对于它的最小值,请参阅关于立即传递的说明)。这两个操作都可以通过CLI或管理面板完成,并且可以在已声明的队列上完成。通过这种方式,您的发布者可以像往常一样发布消息,甚至旧的使用者也可以第一次像预期的那样工作,但同时新的使用者可以从新队列中消费消息,新队列可以手动或以其他方式用新参数预声明

    请注意,在具有大量消息和大量消息流的队列上,满足流控制限制存在一些风险,特别是当您的服务器几乎利用了所有it资源时

    更复杂但更安全的方法(适用于整个消息工作流逻辑发生变化的情况):

    对应用程序进行所有必要的更改,并与现有代码库并行运行新的代码库,但要在不同的RabbitMQ vhost上运行(甚至使用单独的服务器,这取决于应用程序的负载和硬件)。实际上,可以在同一个vhost上运行,但可以更改交换和队列名称,但即使是书面形式,它听起来也不好闻。设置新应用程序后,将其与旧应用程序切换,并运行从旧队列到新队列的消息迁移(或者让旧系统清空队列)。它保证了无缝迁移,停机时间最短。如果您将部署自动化,整个过程将不会花费太多精力

    注意:在上述任何情况下,如果可以的话,让老用户清空队列,这样您就不需要手动迁移消息

    更新:


    您可能会发现非常有用,尤其是在交换和队列之间移动消息,甚至在不同的vhost和服务器之间。这是在队列/交换机之间迁移邮件的最快、最安全的方法。

    谢谢您的回答。vhost解决方案对我来说也是最干净的,但它带来了一个问题:所有分布式发布者都必须跟踪他们发布的位置,并在每次更改时进行相应的更新。有没有一种简单的方法让他们可以直接指向同一个地方,然后我们可以将它路由到正确的Vhost?我认为,若这些细节是可以避免的,出版商就不应该关心这些细节。但这可能更像是一个系统管理问题,而不是RabbitMQ问题。通常vhost是可配置的选项(或者至少应该是),所以更改它不应该是一个问题。请注意,如果您不想(或者您负担不起)停机,只需并行运行新的发布者和使用者,然后停止原始发布者,将消息从旧vhost迁移到新vhost。但如果可以的话,让你的应用程序在第一阶段队列声明失败后存活下来,然后