5

我目前正在为基于事件的分布式系统构建参考架构,其中事件使用普通的旧表(没有 SQL Server 服务代理)存储在 SQL Server Azure 数据库中。

事件将使用将轮询队列以获取新事件消息的工作角色进行处理。

在我的研究中,我看到了许多允许多个处理器处理队列外消息的解决方案。我看到的许多模式的问题是当多个进程试图访问单个消息队列时,管理锁定等增加了复杂性。

我知道传统的队列模式是从一​​个队列中拉出多个处理器。但是,假设可以按任何顺序处理事件消息,是否有任何理由不在队列与其队列处理器之间创建一对一的关系并在不同队列之间进行负载平衡?

队列_1 => 处理器
_1 队列_2 => 处理器_2

此实现避免了管理跨多个处理器对队列的并发访问所需的所有管道。事件发布者可以使用任何负载平衡算法来决定将消息发布到哪个队列。

事实上,我在任何搜索中都没有看到这种实现,这让我觉得我忽略了这个设计中的一个主要缺陷。

编辑

这篇文章引发了关于使用数据库表作为队列与 MSMQ、Azure 队列等的争论。我知道有许多本机队列选项可供我使用,包括 Azure AppFabric 中的持久消息缓冲区。我已经评估了我的选项并确定 SQL Azure 表就足够了。我的问题的目的是讨论对单个队列使用多个处理器与每个队列一个处理器。

4

4 回答 4

5

有关此主题的更详细讨论,请参阅使用表作为队列。问题不仅在于您如何访问“队列”,还在于您如何对其进行索引,聚集索引必须允许直接查找下一行以出列,否则您将不断死锁。

你希望你的处理器竞争到同一个队列,通过分散到不同的队列来平衡负载是一种反模式。它会导致车队和人为延迟,其中您的项目在延迟处理器后面排队,但其他处理器是空闲和空闲的,因为它们的队列是空的。

于 2011-05-04T19:39:19.820 回答
1

作为队列的表很容易做到。请在此处查看我的 SO 答案:SQL Server Process Queue Race Condition

于 2011-05-04T18:49:22.797 回答
1

正如 S.Lott 提到的,您可以使用一些消息队列机制。MSMQ 在 Windows Azure 中并没有真正的帮助,但 Windows Azure 已经有一个持久的队列机制。您可以轻松地设置每个工作角色实例来读取一个(或多个)队列项。读取队列项目后,它在您指定的任何时间长度内都是“不可见的”(如果未指定时间,则为 30 秒)。队列消息最大可达 8K,它们被认为是“持久的”——所有 Azure 存储至少被复制 3 次(SQL Azure 也是如此)。

虽然您可以实现 gbn 所描述的内容,但我真的认为在 Windows Azure 中工作时您应该考虑使用本机 Azure 队列服务。您将能够轻松地扩展到多个队列消费者,而不必担心并发或特殊的负载平衡代码 - 只需增加(或减少)实例数。

有关 Windows Azure 队列的更多信息,请查看Azure 平台培训工具包- 有几个简单的实验室可以引导您了解队列基础知识。

于 2011-05-04T19:14:02.223 回答
0

在我看来,您缺少的一点是,当使用队列时,重要的一点是订单被保存,并且一旦它在队列中发生任何事情,它都不会丢失。

现在 pollers 进程可能会死掉,他们会有很多不同的问题,你不用管,队列是订单安全的地方。

轮询器不需要相同级别的鲁棒性。例如, Postfix是一个非常安全的邮件传输器实现,其中消息队列在很多级别中使用(应用程序中的每个子系统需要不同的安全级别与其他队列进行通信) - 您可以关闭电源,您不会丢失任何邮件,工人可能会死得很惨,邮件不会。

编辑

这意味着基本用法是存储订单,而忽略工作人员将对此做什么,还有多少工作人员还活着等等。因此,处理多个队列的唯一原因是为您的订单管理多个目的地(应用程序逻辑)和不管理工人应该与他们合作的方式(脱钩)。

于 2011-05-04T19:24:20.763 回答