【问题标题】:RabbitMQ - How to ensure two queues stay synchronizedRabbitMQ - 如何确保两个队列保持同步
【发布时间】:2017-11-29 15:08:57
【问题描述】:

我有两个队列,它们都有不同的数据类型,它们在我的应用程序处理时会相互影响,因此异步处理来自两个队列的消息会导致数据完整性问题。

我很好奇确保在任何给定时间只有一位消费者在消费的最佳做法。以下是我到目前为止的总结:

EventMessages 接收有关外部事件的信息,这些事件可能会或可能不会对排队/现有的PurchaseOrderMessages 产生影响。

由于我们预计我们将消耗更多 PurchaseOrderMessage 而不是 EventMessage,也许我们应该在处理 PurchaseOrderMessage 队列中的任何内容之前确保 EventMessage 队列为空(通过 API) - 但这样会得到进入等待时间等问题,这一切都需要尽可能接近实时发生。

如果有一种方法可以简单地暂停 Consumer A 直到 Consumer B 处于静止状态,这可能是最简单的解决方案,我只是不太确定我需要朝哪个方向发展。

更新

为了提供一些额外的上下文,PurchaseOrderMessage 将包含起点和终点。

EventMessage 还包含位置数据。

每次处理PurchaseOrderMessage 时,它都会查询当前EventMessage 记录中与PurchaseOrder 的起点和终点相匹配的任何Event 位置并创建关联。

每次处理EventMessage 时,它都会查询当前PurchaseOrderMessage 记录以查找与Event 匹配的任何目的地来源并创建关联。

如果同步队列不是一个好的解决方案,当EventMessagesPurchaseOrderMessages 同时发布到应用程序时,还有什么替代方法可以确保不会遗漏任何关联?

更新 2

最终,此数据将提供一个 UI,该 UI 将包含 PurchaseOrders 列表以及可能影响其交付日期的事件。由于最终用户正在渲染/检索PurchaseOrder 数据,因此执行“事件检查”会太慢,这就是我们想要在处理/使用它们时执行它的原因。

【问题讨论】:

  • 目前还不清楚您的消息的哪一部分需要同步。我的猜测是您需要重新设计服务的设计。
  • 存储关联的目的是什么?
  • 另一个好问题!我已经用该信息更新了问题。
  • 那很好,但我还是不明白。采购订单队列完成了什么,为什么事件会影响队列中的某些内容?
  • 为了继续 DisneyExample 主题,我从在线迪士尼商店订购了一些米老鼠拖鞋 (PurchaseOrder),从洛杉矶运送到纽约,但事实证明在纽约配送中心可能会影响我的交货估算。我希望能够查看我的所有订单并查看可能影响他们准时到达目的地的事件

标签: rabbitmq queue message-queue


【解决方案1】:

让我从前面的底线开始 - 从表面上看,你所问的没有意义。

队列永远不需要同步。 这样做的想法完全违背了排队的目的。有关背景信息,请访问this answer

让我们考虑一下现实生活中我们遇到多个队列的一些常见地方:

  1. 电影院(票房、特许柜台、引座员)
  2. 主题公园(小吃店、主要景点)
  3. 生产车间(每个工位可能有排队等待处理)

在每个例子中,从队列中的对象的角度来看,它一次只能等待一个。它不能在一个队列中等待而在另一个队列中等待 - 这样的事情在物理上是不可能的。

您的示例似乎采用了两个完全不相关的事物并将它们合并在一起。你有一个PurchaseOrder 对象的队列——但队列是干什么用的?这相当于去迪士尼世界并在Customer 队列中等待——这样的队列的目的是什么?如果目的不明确,就不是真正的队列。

解决您的问题

首先需要通过明确定义对PurchaseOrder 执行的各种操作来解决此特定问题,然后为每个操作创建队列。如果这些操作是真正同步的,那么您的业务逻辑应该被编码为在开始另一个操作之前等待一个操作完成。在这种情况下,如果PurchaseOrder 在未满足先决条件的情况下到达队列的头部,则将被视为例外。

请记住,消息队列通常服务于无状态操作。好的设计要求队列中的消息包含处理器处理消息所需的所有信息。如果您不遵守这一点,那么您的数据库将成为您系统的单点争用 - 虽然这不是一个无法克服的问题,但它确实会使设计更加复杂。

在多个队列中等待

现在,如果您曾经去过迪士尼世界,您也会知道他们有一个名为 FastPass+ (FP+) 的东西,它允许持有者在指定的景点免排队。迪士尼每小时为园区内的每个主要景点分配一定数量的名额,客人每天最多可以申请三个 FP+。 FP+ 时间分配为一小时块,客人不能有两个重叠的 FP+ 时间块。一旦为骑行发放了所有 FP+ 插槽,就不再提供可用的插槽。 FP+ 系统确保这些规则得到执行,独立于每次骑行的备用队列。从本质上讲,通过使用 FastPass+,客人可以虚拟地排多队等候,并在访问期间体验更多景点。

如果您无法分析您的设计并提出替代方案,也许 FastPass+ 方法可以帮助缓解一些瓶颈。

免责声明:我不为迪士尼工作,但我每个月都会去多次,总是先获得我的 FastPass

【讨论】:

  • 感谢您的精彩回复。你说得对,我需要更好地解释队列的目的以及之后的流程。我已使用该信息更新了原始问题。
猜你喜欢
  • 1970-01-01
  • 2011-12-01
  • 1970-01-01
  • 2019-07-31
  • 1970-01-01
  • 2013-12-22
  • 2013-06-12
  • 2019-08-11
  • 1970-01-01
相关资源
最近更新 更多