为发送到服务的请求确定优先级,以便高优先级请求能够得到比低优先级请求更快速地接收和处理。 在向各个客户端提供不同服务级别保障的应用程序中,此模式非常有用。
应用程序可以将特定任务委托给其他服务,例如执行后台处理,或与其他应用程序、服务集成。 在云中,消息队列通常用于将任务委托给后台处理。 在许多情况下,服务接收请求的顺序并不重要。 但在某些情况下,必须确定特定请求的优先级。 相对于应用程序以前发送的优先级较低的请求,这些请求应先于得到处理。
队列通常是先入先出 (FIFO) 结构,使用者通常是按将消息发布到队列的相同顺序接收的。 但是,某些消息队列支持优先级消息传送。发布消息的应用程序可以分配优先级,并且队列中的消息自动重新排序,以便优先级高的消息先于优先级较低的消息收到。 该图显示具有优先级消息传送的队列。
大多数消息队列实现都支持多个使用者(遵照使用者竞争模式),使用者进程数可以根据需要增加或减少。
在不支持基于优先级的消息队列的系统中,替代解决方法是将每个优先级的消息保持一个单独队列。 应用程序负责将消息发布到相应的队列。 每个队列可以有单独的使用者池。 优先级较高的队列可以有比优先级较低的队列更大的使用者池,并且在速度更快的硬件上运行。 下图显示了对每个优先级使用单独的消息队列。
此策略的变体是使用单个使用者池,这些使用者首先检查高优先级队列中是否有消息,然后才从优先级较低的队列中提取消息。 使用单个使用者进程池的解决方案与使用多个队列的解决方案存在一些语义上的差异:前者使用单个队列支持具有不同优先级的消息,或使用多个队列,每个队列处理一种优先级的消息;而后者对每个队列使用一个单独池。
在单个池方法中,优先级较高的消息始终先于优先级较低的消息得到接收和处理。 理论上,可以不断取代并且可能永远不会处理优先级非常低的消息。 在多个池方法中,始终都会处理优先级较低的消息,只不过不会像优先级较高的消息那样快(具体要取决于它们具有的可用池和资源的相对大小)。
使用优先级排队机制可以提供以下好处:
在决定如何实现此模式时,请考虑以下几点:
在解决方案的上下文中定义优先级。 例如,高优先级可能表示消息应在 10 秒内处理。 确定处理高优先级项目的要求,以及应分配以满足这些条件的其他资源。
决定是否必须在任何低优先级项目之前处理所有的高优先级项目。 如果消息由单个使用者池处理,则必须提供这样一种机制:如果较高优先级的消息出现,该机制可以取代和暂停正在处理低优先级消息的任务。
在多队列方法中,使用单个使用者进程池侦听所有队列,而不是每个队列都有专用的使用者池时,使用者必须应用一种算法,以确保始终都先为较高优先级队列中的消息提供服务,之后才是较低优先级队列中的消息。
监控高优先级和低优先级队列的处理速度,确保这些队列中的消息按照预期速度进行处理。
如果需要保证低优先级的消息得到处理,则必须实施具有多个使用者池的多消息队列方法。 或者,在支持消息优先级的队列中,可以随时间的推移动态提高已排队消息的优先级。 但是,这种方法取决于提供上述功能的消息队列。
对每个消息优先级使用单独的队列,这种方法最适用于具有少量定义完善的优先级的系统。
消息优先级可以由系统按逻辑方式确定。 例如,可以将它们指定为“付费客户”或“非费付费客户”,而不是采用显式高和低优先级消息。相对于非费付费客户的消息,系统可以分配更多的资源来处理付费客户的消息,具体要取决于业务模型。
可能会有与检查队列消息相关的财务和处理成本(每次发布或检索消息时,以及每次查询队列中的消息时,某些商业消息传递系统都会收取少量费用)。 上述成本会在检查多个队列时增加。
可以基于池所服务的队列长度动态调整使用者池的大小。
此模式在以下情况非常有用: