在RabbitMQ中混合Pub / Sub和工作队列

我正在评估使用RabbitMQ作为消息队列/消息总线,并一直在查看RabbitMQ页面上的示例教程 。

我正在寻找教程未涵盖的特定场景,我不确定是否以及如何通过RabbitMQ做到这一点。

设置

  • 让我们假设我得到了一项服务,我们称之为“采购订单”,我还需要其他服务,称为“物流”和“会计”。

  • 发送订单时,我想通过RabbitMQ将其作为消息发送。

  • 有2个“帐户”和3个“后勤”服务

确保“帐户”和“后勤”仅处理消息一次的正确方法是什么? 如果我理解正确,使用pub / sub将导致消息被处理两次(帐户)或三次(物流)。

使用工作队列和prefetch = 1,它将确保只有一个获得它,但我有2个服务,并希望每种类型的服务获得一个。

有没有办法将两者结合起来并为每个服务设置工作队列,而不向两个不同的交换机发送2个单独的事件/消息?

如果我理解正确,使用pub / sub将导致消息被处理两次(帐户)或三次(物流)。

根据您的描述,每个worker可能有1个队列,并且您将消息路由到所有工作队列。 因此,每个工作人员都会获得该消息的副本,因为您将消息路由到所有队列。

你想要的是一个“帐户”队列和一个“逻辑”队列。 您将从单个帐户队列中读取多个帐户服务; 对于物流服务/队列也是如此。

设置prefetch = 1也很重要。 这可以防止您同时向单个工作人员读取太多消息。

有没有办法将两者结合起来并为每个服务设置工作队列,而不向两个不同的交换机发送2个单独的事件/消息?

是的 – 不要使用扇出交换。 使用主题或直接交换,并使用多个路由键将单个邮件路由到帐户和后勤队列。

确保“帐户”和“后勤”仅处理消息一次的正确方法是什么?

没有办法保证这一点,100%。 在某些时候,即使使用我所描述的正确设置,您将遇到网络故障或工作人员崩溃或其他问题,并且消息将被处理两次。 你必须在你的设计中考虑到这一点,在你的消息处理中使用某种forms的幂等性 。

希望有所帮助!