如何在现实世界中的多个队列读?(How to read from multiple queues i

2019-09-17 23:42发布

这里有一个理论问题:

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

我打算用1个Web角色和1个辅助角色“最小”这一部署到Windows Azure。

一个人如何从以适当的方式所有20个队列读? 这是我脑子里想的,但我有这个很少或根本没有真实世界的实践经验:

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

这导致有20个线程(或21?),以及20个队列正在积极调查,造成了大量浪费消息(每次轮询空队列它被标榜为消息时间)。

你怎么解决这个问题?

Answer 1:

我读了其他答案(很好的答案),并希望把我自己的旋转这一点。

使用Windows Azure队列坚持,因为@Lucifure被描述:我真的没有看到,除了两个方案多队列的需要:

  • 你想不同的优先级。 你想的最后一件事是陷入了数百颗低优先级的消息背后的高优先级的消息。 创建这些高保真优先级队列。
  • 消息读取数+删除操作将要超过每秒500次交易的目标。 在这种情况下,创建多个队列,传播跨存储分区的交易量(和存储账户将向上每秒5K交易的处理)。

如果坚持使用单个队列(基于存储,而不是服务总线),则可以在同一时间(最多32个)读取的消息的块。 您可以轻松地工作了格式,可帮助您区分消息类型(也许用一个简单的前缀)。 然后,只需用手关闭消息以供处理的适当线程。 服务总线队列没有多消息的内容,他们虽然允许预取(这会导致缓冲的消息被下载到缓存)。

一个队列在许多的优点:你删除(或大大减少)的问题“有没有消息队列多,导致空读。”

如果你需要更多的吞吐量,可以随时杀青线程执行队列中读取和调度的数量。

请记住,每个删除是原子; 没有配料。 而据队列轮询云:你想想补偿的权利。 你不需要阅读成功的消息(或消息块)之后打退堂鼓了。 刚背过,当你不尝试读取后得到任何东西。

在服务总线队列一个大好处:Windows Azure的队列,为您提供一个近似的邮件数(考虑向外扩展到多个实例时,这是非常有用)。 服务总线队列不提供此。



Answer 2:

一种替代的策略是使用单一的或更小的队列,使得一个队列可以支持一个以上的类型的消息。 这种方法更容易管理和便宜,如果你的系统架构能够支持。

在现实世界中我已经成功地使用多个队列(可扩展性的目的),每个队列由定时器事件触发一个单独的线程读取。 根据在该队列和应用需要的负荷时,定时器事件改变为服务于动态变化的时间间隔的队列。



Answer 3:

如果存储队列回退机制是不够的你,我建议你考虑服务总线队列。 随着服务总线队列你不会做这样的攻击性投票。

你仍然需要实现轮询队列中环,但接收超时使得比使用存储队列时,你必须不断轮询机制变得更轻。

在下面的例子中,我试图从队列中接收的消息。 如果没有找到消息将保持连接打开30秒,看看是否有什么新的用武之地,如果30秒后没有消息到达,Receive方法将返回null(和我将有一个循环试图再次调用接收)。 需要注意的是,最大的超时时间为24

MessagingFactory factory = MessagingFactory.Create(ServiceBusEnvironment.CreateServiceUri("sb", ServiceNamespace, string.Empty), credentials); 
QueueClient myQueueClient = factory.CreateQueueClient("TestQueue");
myQueueClient.Receive(new TimeSpan(hours: 0, minutes: 0, seconds: 30));

你想从阅读每个队列弹出线程是一个好主意,但看到的CLR线程池,你也应该考虑接收异步消息(使用TaskFactory.FromAsync为例)的容量限制: http://msdn.microsoft。 COM / EN-US /库/ windowsazure / hh851744.aspx



文章来源: How to read from multiple queues in real-world?