在 FIFO 排队系统中,实现优先级消息传递的最佳方式是啥

Posted

技术标签:

【中文标题】在 FIFO 排队系统中,实现优先级消息传递的最佳方式是啥【英文标题】:In a FIFO Qeueing system, what's the best way the to implement priority messaging在 FIFO 排队系统中,实现优先级消息传递的最佳方式是什么 【发布时间】:2010-11-11 11:19:03 【问题描述】:

对于不始终支持优先级消息的面向消息的中间件(例如 AMQP),当队列只有 FIFO 语义时,实现优先级消耗的最佳方式是什么?一般用例是这样一个系统,当队列中存在大量消息积压时,消费者在接收优先级较低的消息之前接收优先级较高的消息。

【问题讨论】:

可以有多个队列吗?如果是这样,我建议为高优先级消息设置一个单独的队列,该队列在标准队列之前首先查询,仅在优先级队列为空时使用。我不知道这是否符合您的情况,但这是我的第一个想法。 我同意 CSharpWithJava。我目前正在做一个大型消息传递应用程序,我认为从您的问题来看,您需要多个队列,因此您可以将较低 pri 消息卸载到较低 pri 队列,并立即读取高 pri。 注意 AMQP 确实具有从 0-9-1 规范 (rabbitmq.com/amqp-0-9-1-reference.html) 开始的优先级消息 【参考方案1】:

鉴于给定的单个队列仅支持 FIFO,您当然必须引入多个队列、中介或拥有更复杂的消费者。

可以通过多种方式处理多个队列。生产者和消费者可以同意在它们之间有两个队列,一个用于高优先级,一个用于后台任务。

如果您的生产者受限于单个队列,但您可以控制消费者,请考虑在路径中引入扇出路由器。所以 producer->Router 是一个单独的队列,然后路由器有两个队列到消费者。

另一种可能不太理想的解决方法是让您的消费者旋转一个线程到队列前面,然后在内部分派工作。类似于上面的路由器版本,但在单个应用程序中。这样做的缺点是在您的应用程序中传输多条消息,如果发生故障,这可能会使恢复变得复杂。

不要忘记考虑有效的低优先级事件的饥饿,不管它们是什么,如果它们中的一些应该被处理,即使还有更高优先级的事件仍然存在。

【讨论】:

这或多或少正是我们为工作中的项目实施此策略的人。分级优先系统的多个队列。我们不太担心饥饿,因为在这种情况下我们可以重新发布具有更高优先级的重要低优先级消息;在大多数情况下,多余的工作被处理,以允许这样做。

以上是关于在 FIFO 排队系统中,实现优先级消息传递的最佳方式是啥的主要内容,如果未能解决你的问题,请参考以下文章

Java 实现 FIFO 缓存算法

ActiveMQ 或任何消息队列 - FIFO 要求

Perl 的排队系统

管道通信为啥比共享内存效率低

关于优先级队列的实现

一种FIFO实现原理