如何从现实世界中的多个队列中读取?

Leo*_*ens 3 message-queue azure azure-storage-queues azure-servicebus-queues

这是一个理论问题:

当我使用消息队列构建应用程序时,我将需要多个队列支持不同的数据类型以用于不同的目的。假设我有 20 个队列(例如,一个用于创建新用户,一个用于处理新订单,一个用于编辑用户设置等)。

我将使用“最少”1 个 Web 角色和 1 个辅助角色将其部署到 Windows Azure。

如何以正确的方式从所有这 20 个队列中读取数据?这就是我的想法,但我对此几乎没有或没有现实世界的实践经验:

创建一个在辅助角色“main”类中产生 20 个线程的类。让这些线程中的每一个都执行一个方法来轮询不同的队列,并让所有这些线程在每次轮询之间休眠(当然还有增加休眠时间的回退机制)。

这导致有 20 个线程(或 21 个?)和 20 个正在主动轮询的队列,从而导致大量消息浪费(每次轮询空队列时,它都被计为消息)。

你怎么解决这个问题?

Dav*_*gon 5

我阅读了其他答案(非常好的答案)并想对此发表自己的看法。

坚持使用 Windows Azure 队列,正如@Lucifure 所描述的:除了两种情况外,我真的不认为需要多个队列:

  • 你想要不同的优先级。您最不想要的就是一条高优先级消息卡在数百条低优先级消息后面。为这些创建一个高优先级队列。
  • 消息读取+删除的数量将超过每秒 500 个事务的目标。在这种情况下,创建多个队列,将事务量分布在存储分区之间(并且一个存储帐户每秒将处理 5K 以上的事务)。

如果坚持使用单个队列(基于存储,而不是服务总线),则可以一次读取消息块(最多 32 个)。您可以轻松地制定一种格式来帮助您区分消息类型(可能带有简单的前缀)。然后,只需将消息交给适当的线程进行处理。服务总线队列没有多消息读取,尽管它们允许预取(这会导致将缓冲的消息下载到缓存中)。

一个队列优于多个队列的优势:您可以消除(或大大减少)“许多队列没有消息,导致空读取”的问题。

如果您需要更多吞吐量,您可以随时增加执行队列读取和分派的线程数量。

请记住,每个删除都是原子的;没有批处理。就队列轮询而言:考虑退避是正确的。成功读取消息(或消息块)后,您无需退出。当您尝试阅读后没有得到任何东西时,请退后。

与服务总线队列相比,一个不错的优势是:Windows Azure 队列为您提供了一个大致的消息计数(这在考虑横向扩展到多个实例时非常有用)。服务总线队列不提供此功能。

  • 只需使用一些独特的前缀格式化消息。然后您的队列读取代码查看前缀并决定如何处理每条消息。例如:`RENDER|\raw\image1.jpg|\rendered\image1.jpg` 和`THUMBNAIL|\raw\image1.jpg|\thumbs\image1.jpg`。通过分隔符`'|'`解析,检查它是哪种消息类型,并将其传递给适当的线程。注意:队列消息是二进制或字符串。想出你想要的任何格式。只是举个简单的例子。 (2认同)