云计算设计模式(十六)——优先级队列模式

优先发送到服务,以便具有较高优先级的请求被接收和高于一个较低优先级的更快速地处理请求。这种模式是在应用程序是有用的,它提供不同的服务级别保证或者针对独立客户。

背景和问题

应用程序可以委托给其他服务的具体任务;例如,为了执行后台处理或与其他应用程序或服务的整合。在云中,消息队列通常用于将任务委派给后台处理。在许多情况下,请求由服务接收的顺序是不重要的。然而,在某些情况下,可能需要优先考虑的具体要求。这些要求必须早于较低优先级的其他可能先前已发送由应用程序进行处理。

解决方案

队列通常是先入先出(FIFO)结构,而消费者通常会收到他们发布到队列中的顺序相同的消息。然而,一些消息队列支持优先级的消息传递;应用程序发布一条消息可以分配优先级的消息,并在队列中的消息会自动重新排序,使得具有较高优先级的消息将这些优先级较低的前被接收。图1示出了一个队列,它提供优先权的消息。

图1  - 使用支持消息优先级排队机制

注意:

大多数消息队列的实现支持多个消费者(以下的竞争消费者模式)和消费过程的数量可以按比例增加或减小的需求支配。

在不支持基于优先级的消息队列系统中,一种替代的解决方案是为每一个优先级的独立队列。该应用程序负责将邮件投递到适当的队列。每个队列可以有一个单独的消费者池。高优先级队列可以有更快的硬件比低优先级队列中运行的消费者一个更大的泳池。图2示出了这种方法。

图2 - 使用不同的消息队列为每个优先级

这种策略的变化是有消费者认为检查对高优先级队列中的消息,然后再才开始从低优先级队列中读取消息,如果没有更高优先级的消息都在等待的一个池。还有,使用消费过程的一个池的溶液之间的一些语义差异(或者使用支持不同的优先级或多个队列,每个处理一个单一的优先级消息的消息的单个队列),以及使用多个队列用溶液为每个队列一个单独的游泳池。

在单池的做法,高优先级的消息总是会收到以前低优先级的消息处理。在理论中,具有非常低的优先级的消息可以被不断地取代,并且可能永远不会被处理。在多池的方法,较低优先级的报文将总是被处理,只是不一样迅速的那些更高的优先级的(取决于池和它们具有可用资源的相对大小)。

使用优先级排队机制可提供以下优点:
•它允许应用程序以满足必要的可用性或性能优先的业务需求,如提供不同级别的服务,以客户的特定群体。
•它可以帮助最大限度地降低运营成本。在单队列的方式,你可以缩减用户的数量,如果有必要的。高优先级消息仍将被首先处理(虽然可能更慢),和低优先级的消息可能会延迟更长。如果您已实现与消费者的每一个单独的队列池多个消息队列的方式,可以减少消费者的池低优先级队列,或者甚至停止所有监听的讯息的消费者暂停处理一些非常低优先级队列这些队列。
•在多个消息队列的方法可以帮助划分的基础上处理要求的消息,以最大限度地提高应用程序的性能和可扩展性。例如,重要的任务,可以优先被立即运行,而不太重要的后台任务可以被安排在不太繁忙的时段运行的接收器来处理接收处理。

问题和注意事项

在决定如何实现这个模式时,请考虑以下几点:
•定义优先级的解决方案的情况下。例如,“高优先级”可能意味着,信息应该在十秒内进行处理。标识要求处理高优先级的项目,以及其他什么资源必须分配给符合这些标准。
•确定是否所有高优先级的项目必须在任何优先级较低的项目之前进行处理。如果该消息是由消费者的一个池被处理,可能有必要提供一种可抢先和暂停正在处理的低优先级消息,如果更高优先级的消息,有一个任务的机制。
•在多个队列中的方法,使用该监听所有的队列,而不是一个专门的客户池的每个队列的消费过程的一个池时,消费者必须应用一种算法,以确保它总是从那些从低之前较高优先级的队列提供服务的消息优先级队列。
•监视处理的高和低优先级队列中的速度,以确保在这些队列中的消息的预期的速率进行处理。
•如果需要,以保证低优先级的消息将被处理时,可能有必要实现与消费者的多个池的多个消息队列的方法。或者,在一个支持消息优先队列,它可能会动态地增加一个排队的消息的优先级,因为它的年龄。然而,该方法依赖于消息队列提供此功能。
•使用单独的队列中每个消息优先级最适合有少数明确定义的优先级系统。
•消息优先级可以通过系统逻辑决定的。例如,而不是明确的高和低优先级的消息,他们可以被指定为“自费客户”,或“非自费的客户。”根据您的商业模式,你的系统可能会分配更多的资源,从收费处理消息付费用户比非自费的。
•有可能是检查队列的消息相关联的金融和处理成本(一些商业邮件系统的消息被发布或检索每次收取一小笔费用,每次一个队列中查询消息)。检查多个队列时,该成本将有所增加。
•它可以是能够动态调整的基础上,该池所服务的队列的长度消费者的一个池的大小。欲了解更多信息,请参阅自动缩放指导。

何时使用这个模式

这种模式非常适合场景:
•系统必须处理可能有不同的侧重点多个任务。
•不同的用户或租户应配以不同的优先级。

例子

微软Azure不提供经过整理的本地支持邮件自动优先级排队机制。然而,它确实提供了Azure的服务总线主题和订阅,支持排队机制,提供邮件过滤,具有多种灵活的功能,使其非常适合用在几乎所有的优先级队列的实现在一起。

一个Azure的解决方案,可以实现服务总线话题,其中一个应用程序可以发布消息,以同样的方式作为一个队列。消息可以包含在应用程序定义的自定义属性的形式的元数据。服务总线订阅可以与主题相关联,并且这些订阅可以筛选根据它们的属性信息。当一个应用程序将消息发送到一个主题,该消息被定向到从那里它可以被消费者阅读相应的订阅。消费者的过程可以检索使用相同的语义消息队列(订阅是一个逻辑队列)从一个订阅消息。

图3示出了使用的Azure服务总线主题和订阅的解决方案。

图3 - 实现与Azure的服务总线主题和订阅优先级队列

在图3中的应用程序创建多个消息和每个消息与价值分配被称为优先级的自定义属性,无论是高还是低。该应用程序的帖子,这些消息的一个话题。这个主题有两个相关的订阅,这两个滤波器的消息通过检查优先级属性。一位接受认购,其中优先级属性设置为高的消息,而其他接受其中优先级属性设置为低的消息。消费者池读取每个订阅的消息。高优先认购有较大的游泳池,而这些消费者可能会更强大(且昂贵)的计算机上运行有提供比消费者在低优先级池的更多资源。

请注意,没有什么特别的高,低优先级消息在这个例子中指定。这些仅仅是指定为每个消息中的属性的标签,并用于引导消息发送到一个特定的订阅。如果附加的优先级是必需的,它是比较容易地创建进一步的订阅和消费者进程池来处理这些优先级。

在可用于此引导代码时Queue解决方案包含这种方法的一个实现。该解决方案包含一个名为PriorityQueue.High和PriorityQueue.Low两个工作角色的项目。这两个辅助角色继承的类被称为PriorityWorkerRole它包含用于连接到一个指定的预订中OnStart方法的功能。

该PriorityQueue.High和PriorityQueue.Low辅助角色连接到不同的预订,他们的配置设置来定义。管理员可以配置每个角色的不同数量要运行;通常会有比PriorityQueue.Low工作者角色的PriorityQueue.High辅助角色更多的实例。

在PriorityWorkerRole类的Run方法安排虚拟ProcessMessage的方法(在PriorityWorkerRole类定义)的队列中接收到的每个消息被执行。下面的代码显示了运行和ProcessMessage的方法。在类的QueueManager,在PriorityQueue.Shared项目定义,提供了辅助方法使用的Azure服务总线队列。

[csharp] view plaincopy

  1. public class PriorityWorkerRole : RoleEntryPoint
  2. {
  3. private QueueManager queueManager;
  4. ...
  5. public override void Run()
  6. {
  7. // Start listening for messages on the subscription.
  8. var subscriptionName = CloudConfigurationManager.GetSetting("SubscriptionName");
  9. this.queueManager.ReceiveMessages(subscriptionName, this.ProcessMessage);
  10. ...;
  11. }
  12. ...
  13. protected virtual async Task ProcessMessage(BrokeredMessage message)
  14. {
  15. // Simulating processing.
  16. await Task.Delay(TimeSpan.FromSeconds(2));
  17. }
  18. }

该PriorityQueue.High和PriorityQueue.Low辅助角色既覆盖ProcessMessage的方法的默认功能。下面的代码显示了ProcessMessage的方法为PriorityQueue.High辅助角色。

[csharp] view plaincopy

  1. Copy
  2. protected override async Task ProcessMessage(BrokeredMessage message)
  3. {
  4. // Simulate message processing for High priority messages.
  5. await base.ProcessMessage(message);
  6. Trace.TraceInformation("High priority message processed by " +
  7. RoleEnvironment.CurrentRoleInstance.Id + " MessageId: " + message.MessageId);
  8. }

当一个应用程序将消息发布到与所使用的PriorityQueue.High和PriorityQueue.Low辅助角色的订阅相关联的主题,它指定了优先使用优先级的自定义属性,如在下面的代码示例。此代码(这是在PriorityQueue.Sender项目WorkerRole类实现),使用的QueueManager类的SendBatchAsync辅助方法发帖分批的话题。

[csharp] view plaincopy

  1. // Send a low priority batch.
  2. var lowMessages = new List<BrokeredMessage>();
  3. for (int i = 0; i < 10; i++)
  4. {
  5. var message = new BrokeredMessage() { MessageId = Guid.NewGuid().ToString() };
  6. message.Properties["Priority"] = Priority.Low;
  7. lowMessages.Add(message);
  8. }
  9. this.queueManager.SendBatchAsync(lowMessages).Wait();
  10. ...
  11. // Send a high priority batch.
  12. var highMessages = new List<BrokeredMessage>();
  13. for (int i = 0; i < 10; i++)
  14. {
  15. var message = new BrokeredMessage() { MessageId = Guid.NewGuid().ToString() };
  16. message.Properties["Priority"] = Priority.High;
  17. highMessages.Add(message);
  18. }
  19. this.queueManager.SendBatchAsync(highMessages).Wait();

本文翻译自MSDN:http://msdn.microsoft.com/en-us/library/dn589794.aspx

时间: 2024-10-25 18:13:50

云计算设计模式(十六)——优先级队列模式的相关文章

云计算设计模式(六)——命令和查询职责分离(CQRS)模式

云计算设计模式(六)--命令和查询职责分离(CQRS)模式 隔离,通过使用不同的接口,从操作读取数据更新数据的操作.这种模式可以最大限度地提高性能,可扩展性和安全性;支持系统在通过较高的灵活性,时间的演变;防止更新命令,从造成合并在域级别上的冲突. 背景和问题 在传统的数据管理系统中,这两个命令(更新数据)和查询(请求数据),针对在一个单一的数据存储库中的相同的一组实体的执行.这些实体可以是在关系数据库中的一个或多个表,如SQL Server的行的子集. 典型地,在这些系统中,所有的创建,读取,

设计模式 ( 十六 ): Mediator中介者模式 -- 行为型

1.概述 在面向对象的软件设计与开发过程中,根据“单一职责原则”,我们应该尽量将对象细化,使其只负责或呈现单一的职责,即将行为分布到各个对象中. 对于一个模块或者系统,可能由很多对象构成,而且这些对象之间可能存在相互的引用,在最坏的情况下,每一个对象都知道其他所有的对象,这无疑复杂化了对象之间的联系.虽然将一个系统分割成许多对象通常可以增强可复用性,但是对象间相互连接的激增又会降低其可复用性,大量的相互连接使得一个对象似乎不太可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,而且对系

Java设计模式(六)合成模式 享元模式

(十一)合成模式 Composite 合成模式是一组对象的组合,这些对象可以是容器对象,也可以是单对象.组对象允许包含单对象,也可以包含其他组对象,要为组合对象和单对象定义共同的行为.合成模式的意义是 保证客户端调用单对象与组合对象的一致性. class TreeNode{ private String name; private TreeNode parent; private Vector<TreeNode> children = new Vector<TreeNode>();

设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为)

 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决.不能解决就推卸给另外个一个部门(对象).至于究竟谁来解决问题呢?政府部门就是为了能够避免屁民的请求与官员之间耦合在一起,让多个(部门)对象都有可能接收请求,将这些(部门)对象连接成一条链,而且沿着这条链传递请求.直到有(部门)对象处理它为止. 样例1:js的事件浮升机制 样例2: 2.问题 假设有多个对象都有

设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)

设计模式 ( 十五 ) 中介者模式Mediator(对象行为型) 1.概述 在面向对象的软件设计与开发过程中,根据“单一职责原则”,我们应该尽量将对象细化,使其只负责或呈现单一的职责,即将行为分布到各个对象中. 对于一个模块或者系统,可能由很多对象构成,而且这些对象之间可能存在相互的引用,在最坏的情况下,每一个对象都知道其他所有的对象,这无疑复杂化了对象之间的联系.虽然将一个系统分割成许多对象通常可以增强可复用性,但是对象间相互连接的激增又会降低其可复用性,大量的相互连接使得一个对象似乎不太可能

云计算设计模式(二)——断路器模式

云计算设计模式(二)--断路器模式 处理故障连接到远程服务或资源时,可能需要耗费大量的时间.这种模式可以提高应用程序的稳定性和灵活性. 背景和问题 在分布式环境中,如在云,其中,应用程序执行访问远程资源和服务的操作,有可能对这些操作的失败是由于瞬时故障,如慢的网络连接,超时,或者被过度使用的资源或暂时不可用.这些故障一般之后的短时间内纠正自己,和一个强大的云应用应该准备使用的策略来处理它们,例如,通过重试模式进行说明. 但是,也可以是其中的故障是由于那些不容易预见的突发事件的情况下,这可能需要更

菜鸟玩云计算之十六:Ubuntu14.04上创建的虚拟机迁移到RHEL6.4

菜鸟玩云计算之十六:Ubuntu14.04上创建的RHEL6.4虚拟机迁移到RHEL6.4主机上 Ubuntu14.04上的 qemu比RHEL6.4上的版本要新,导致在Ubuntu14.04创建的Guest(RHEL6.4)虚拟机复制到RHEL6.4HOST主机上不能运行.为解决这个问题,可以按下面的步骤: 1)在Ubuntu14.04上把qcow2格式的vm转成raw格式的. 2)在RHEL6.4上define raw格式的vm. 既然RHEL6.4支持raw格式的vm,那么可以在Ubunt

设计模式(六)原型模式

一.说说鸣人的影分身 话说鸣人听了水木老师的建议偷出了卷轴并且学会了一招禁术:影分身之术.当鸣人使用影分身之术的时候就会有好多个和鸣人一模一样的人出现,就像复制出来的一样,这种影分身之术在面向对象的设计领域里就叫做原型模式. 二.什么是原型模式 有了上边的鸣人的例子,我们再理解圆形模式的定义应该会更简单了,GOF给它的定义是:用原型实例指定创建对象的种类并且通过拷贝这些原型对象创建新的对象. 在Java中提供了clone()方法来实现对象的克隆,所以原型模式(Prototype)实现变得简单的多

设计模式 十六、Interpreter 解释器(行为模式)

动机(Motivation) 件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化. 种情况下,特定的领域的问题表达式为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的. 意图(Intent) 给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子. interpreter 模式的几个要点 Interpreter模式的应用场合是interpreter模式应用中