Node-amqp - X尝试后拒绝消息

时间:2014-02-13 16:27:01

标签: node.js rabbitmq node-amqp

如何在几次可配置的重新排队尝试后实现拒绝邮件的机制?

换句话说,如果我订阅了一个队列,我想保证相同的消息不会重新传递超过X次。

我的代码示例:

q.subscribe({ack: true}, function(data,headers,deliveryInfo,message) {
  try{
    doSomething(data);
  } catch(e) {
   message.reject(true);
  }
}

2 个答案:

答案 0 :(得分:1)

在我看来,最好的解决方案是在应用程序中处理这些错误,并在应用程序决定无法处理消息时拒绝它们。

如果您不想丢失信息,应用程序应仅在将相同的消息发送到错误队列后拒绝该消息。

代码未经过测试:

q.subscribe({ack: true}, function () {
  var numOfRetries = 0;
  var args = arguments;
  var self = this;
  var promise = doWork.apply(self, args);
  for (var numOfRetries = 0; numOfRetries < MAX_RETRIES; numOfRetries++) {
    promise = promise.fail(function () { return doWork.apply(self, args); });
  }

  promise.fail(function () {
    sendMessageToErrorQueue.apply(self, args);
    rejectMessage.apply(self, args);
  })
})

答案 1 :(得分:0)

一种可能的解决方案是使用您定义的某种散列函数来散列消息,然后检查该散列的缓存对象。如果它在那里,将一个添加到缓存中直到可配置的最大值,如果它不存在,则将其设置为1.这是一个快速而又脏的原型(请注意mcache对象应该在所有订阅者):

var mcache = {}, maxRetries = 3;

q.subscribe({ack: true}, function(data,headers,deliveryInfo,message) {
  var messagehash = hash(message);
  if(mcache[messagehash] === undefined){
    mcache[messagehash] = 0;
  }
  if(mcache[messagehash] > maxRetries) {
    q.shift(true,false); //reject true, requeue false (discard message)
    delete mcache[messagehash]; //don't leak memory
  } else {
    try{
      doSomething(data);
      q.shift(false); //reject false
      delete mcache[messagehash]; //don't leak memory
    } catch(e) {
      mcache[messagehash]++;
      q.shift(true,true); //reject true, requeue true
    }
  }
}

如果消息有GUID,您只需在散列函数中返回它。