2015-12-20 57 views
2

我需要实现优先级队列node.jsSQS。这是我第一次与SQS,所以我想听听你的意见。节点SQS优先级队列

我有3个工作重点:p0,p1和p2,p0是最高的。 p2是最常见的,之后是p0,最后是p1。在数字我可以粗略地说,它是:

p2 ~= 5p0 
p0 >> p1 

他们都是独立作业,以便执行它们的顺序并不重要。

我想出了2个可能的解决方案(这些只是草图,并不真正运行)。

共同

两者

var _ = require('lodash'), 
    Promise = require('bluebird'), 
    sqs = require('some-sqs-module'); 

... 

module.exports.getJob = function() { 
    return getJobByQueuePriority(0); 
    // or... 
    return getJobByJobPriority(0); 
} 

溶液1

使用3个队列,每个优先级之一。样品从每个队列1个工作的优先级进行

var Queues = [p0url, p1url, p2url], 
    currentQueueIndex = 0; 

function getJobByQueuePriority(priority) { 
    return new Promise(function(resolve, reject) { 

     var queueUrl = getNextQueue(priority); 

     if(!_.isEmpty(queueUrl)){ 
      sqs.pullOne(queueUrl) 
       .then(function (job) { 
        // recursive promises??? 
        return job ? resolve(job) : getJobByQueuePriority(priority + 1); 
       }) 
       .catch(function (err) { 
        reject(err); 
       }); 
     } 
    }); 
} 

function getNextQueue(index) { 
    return index >= Queues.length ? '' : Queues[index]; 
} 

解决方案2

使用1队列,并从中收集k任务,然后选择排名最高的工作。

var QUEUE_URL = 'some/sqs/url', 
    JOBS_TO_PULL = 10; 

function getJobByJobPriority (priority) { 
    return new Promise(function (resolve, reject) { 
     sqs.pullMultiple(QUEUE_URL, JOBS_TO_PULL) 
      .then(function (jobs) { 
       var job = getHighestPriorityJob(jobs); 
       resolve(job); 
      }) 
      .catch(function (err) { 
       reject(err); 
      }); 
    }); 
} 

function getHighestPriorityJob(jobs) { 
    var highest = jobs[0]; 

    _.each(jobs, function (job) { 
     if(job.priority < highest.priority){ 
      highest = job; 
     } 

     if(highest.priority == HIGHEST_PRIORITY) break; 
    }); 

    return highest; 
} 

,这里是我想要的消费者

var pq = require('my-priority-queue'); 

function lookForWork() { 
    pq.getJob() 
     .then(function (job) { 
      job ? work(job) : rest(); 
     }); 
} 

function work(job) { 
    // do your work... 

    // search for more work 
    lookForWork(); 
} 

function rest() { 
    (setTimeout(function() { 
     lookForWork(); 
    }, TIME_TO_REST))(); 
} 

这一切都草图所以从来不介意小故障,如果你看到他们。

回答

1

每个优先级的不同队列是最好的方式去imo。它更具可扩展性(例如,如果您需要,您可以添加更多消费者,例如仅处理P2队列)。

通过一个队列,每次从队列中取出消息并且不使用它们时,都会阻止另一个消费者看到它们,直到它们返回。

不确定你的卷是什么,即使SQS很便宜,阅读大量的消息,但不使用它们仍然会产生费用。