简体   繁体   English

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

[英]How to prevent low priority messages on an ActiveMQ Prioritized Queue from being starved?

I am working on a system where we need to implement a prioritized queue. 我正在开发一个需要实现优先级队列的系统。 We have messages with different priorities and we need to process messages based on priority. 我们有不同优先级的消息,我们需要根据优先级处理消息。 Right now, we are looking to use ActiveMQ as our queuing technology for many reasons, one of which is that is supports priority queues. 目前,我们正在寻求使用ActiveMQ作为我们的排队技术,原因有很多,其中一个原因是支持优先级队列。

With a priority queue in ActiveMQ, what is the best way of dealing with starvation? 使用ActiveMQ中的优先级队列,处理饥饿的最佳方法是什么? To be specific, we need to ensure that even a low priority message eventually gets processed even if higher priority messages continue to flood the queue. 具体而言,即使优先级较高的消息继续充斥队列,我们​​也需要确保即使是低优先级的消息也会被处理。 Does ActiveMQ have something built-in? ActiveMQ有内置功能吗? Or do we need to build something of our own to increase the priority as the message ages? 或者我们是否需要建立自己的东西来增加优先级消息的年龄?

a basic way to do this is to bump up the priority when the message gets older 执行此操作的基本方法是在邮件变老时提高优先级

this way a low priority message from say an hour ago is higher priority then a new high priority message 这样,来自一小时前的低优先级消息比新的高优先级消息具有更高的优先级

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;
    }

}

as noted in the comments however a flood from low prio messages from several hours ago will temporarily starve the new high prio messages and to space those properly out will require a more sophisticated method 然而,正如评论中所指出的那样,来自几个小时前的低prio消息的洪水将暂时使新的高prio消息挨饿,而对于空间正常的消息将需要更复杂的方法


another method is using multiple queues, one for each priority and taking several out of the higher priority queue for each taken out of the low priority queue 另一种方法是使用多个队列,每个队列对应一个优先级,并从每个优先级队列中取出多个优先级队列

this last method is only really viable for a low amount of priorities while the first method I provided can handle an arbitrary amount of priorities 最后一种方法对于少量优先级才真正可行,而我提供的第一种方法可以处理任意数量的优先级

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM