如何防止 ActiveMQ 优先队列上的低优先级消息被饿死?

Posted

技术标签:

【中文标题】如何防止 ActiveMQ 优先队列上的低优先级消息被饿死?【英文标题】:How to prevent low priority messages on an ActiveMQ Prioritized Queue from being starved? 【发布时间】:2011-09-17 14:23:16 【问题描述】:

我正在开发一个需要实现优先队列的系统。我们有不同优先级的消息,我们需要根据优先级处理消息。目前,出于多种原因,我们希望使用 ActiveMQ 作为我们的队列技术,其中之一就是支持优先级队列。

使用 ActiveMQ 中的优先级队列,处理饥饿的最佳方法是什么?具体来说,我们需要确保即使更高优先级的消息继续淹没队列,即使是低优先级的消息最终也能得到处理。 ActiveMQ 有内置的东西吗?或者我们是否需要构建自己的东西来随着消息的老化增加优先级?

【问题讨论】:

只是想一想,如果大量的低优先级消息最终被提高优先级,难道不会饿死合法的高优先级消息吗?如果高优先级消息来得那么快,是不是该关闭系统进行修复了? 【参考方案1】:

执行此操作的基本方法是在消息变旧时提高优先级

这样一小时前的低优先级消息的优先级高于新的高优先级消息

public class Message implements Comparable<Message>

    private final long time;//timestamp from creation (can be altered to insertion in queue) in millis the lower this value the older the message (and more important that it needs to be handled)
    private final int pr;//priority the higher the value the higher the priority

    /**
     * the offset that the priority brings currently set for 3 hours 
     *
     * meaning a message with pr==1 has equal priority than a message with pr==0 from 3 hours ago
     */
    private static final long SHIFT=3*60*60*1000; 

    public Message(int priority)
        this.pr=priority;
        this.time = System.currentTimeMillis();
    

    //I'm assuming here the priority sorting is done with natural ordering
    public boolean compareTo(Message other)
        long th = this.time-this.pr*SHIFT;
        long ot = other.time-other.pr*SHIFT;
        if(th<ot)return 1;
        if(th>ot)return -1;
        return 0;
    


正如 cmets 中所指出的,几个小时前的低优先级消息泛滥将暂时使新的高优先级消息饥饿,并且将这些消息适当地隔开将需要更复杂的方法


另一种方法是使用多个队列,每个优先级一个,每个优先级从低优先级队列中取出几个

这最后一种方法仅适用于少量优先级,而我提供的第一种方法可以处理任意数量的优先级

【讨论】:

以上是关于如何防止 ActiveMQ 优先队列上的低优先级消息被饿死?的主要内容,如果未能解决你的问题,请参考以下文章

消息队列学习 --ActiveMQ概念了解

优先队列

OpenCV中的低优先级工作

为啥我需要在 C++ 中使用不同的排序格式来对这个 USACO 代码上的数组和优先级队列进行排序?

数据结构与算法之美-堆的应用

如何在JAVA中创建高优先级有界子队列和低优先级有界子队列