【问题标题】:Mixing of Pub/Sub with workqueues in RabbitMQ在 RabbitMQ 中混合发布/订阅与工作队列
【发布时间】:2015-11-29 16:11:15
【问题描述】:

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

我正在寻找教程未涵盖的特定场景,我不确定是否以及如何通过 RabbitMQ 进行操作。

设置

  • 假设我有一项服务,我们称其为“采购订单”,而我必须使用其他服务,称为“物流”和“会计”。

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

  • 有 2 个“账户”和 3 个“物流”服务

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

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

有没有一种方法可以将两者结合起来并为每个服务设置一个工作队列,而无需将 2 个单独的事件/消息发送到两个不同的交换器?

【问题讨论】:

    标签: c# rabbitmq


    【解决方案1】:

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

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

    您想要的是一个“帐户”队列和一个“后勤”队列。您将从单个帐户队列中读取多个帐户服务;物流服务/队列也一样。

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

    有没有一种方法可以将两者结合起来并为每个服务设置一个工作队列,而无需将 2 个单独的事件/消息发送到两个不同的交换器?

    是的 - 不要使用扇出交换。使用主题或直接交换,并使用多个路由键将单个消息路由到帐户和物流队列。

    确保“帐户”和“物流”只处理一次消息的正确方法是什么?

    没有办法保证这一点,100%。在某些时候,即使像我描述的那样进行了正确的设置,您也会遇到网络故障或工作人员崩溃或其他一些问题,并且一条消息将被处理两次。您必须在设计中考虑到这一点,在消息处理中使用某种形式的idempotence

    希望有帮助!

    【讨论】:

    • 主题不是暗示我必须专门处理服务吗?发送“order.logistic.account”之类的主题并让服务过滤“.logistic.”和/或“..account”?这意味着每次我添加一种新类型的服务(也许是“订单通知”,我都必须编辑主题来添加它?我希望有一些更不可知的方法,所以广播服务不必知道谁接收者是或者如果他们是任何的
    • 消息生产者不知道是否有人在那儿接收消息……但这并不意味着您可以随便扔东西。如果您希望订单通知处理器接收订单通知消息,则必须有一些连接 - 在这种情况下,rabbitmq 交换和队列之间的路由。如果没有正确的路由,每个人都会收到所有消息,并且您最终会在代码中重新构建路由逻辑,而不是利用 rabbitmq 为您做这件事
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 2011-12-18
    • 2016-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多