Node.js 节点amqp-尝试X次后拒绝消息

Node.js 节点amqp-尝试X次后拒绝消息,node.js,rabbitmq,node-amqp,Node.js,Rabbitmq,Node Amqp,如何实现在几次可配置的重新请求尝试后拒绝消息的机制 换句话说,如果我订阅了一个队列,我想保证相同的消息不会被重新传递超过X次 我的代码示例: q.subscribe({ack: true}, function(data,headers,deliveryInfo,message) { try{ doSomething(data); } catch(e) { message.reject(true); } } 一种可能的解决方案是使用您定义的某种散列函数对消息进行散列,然

如何实现在几次可配置的重新请求尝试后拒绝消息的机制

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

我的代码示例:

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

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


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

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

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

未测试代码:

q.subscribe({ack:true},函数(){
var numories=0;
var args=参数;
var self=这个;
var promise=doWork.apply(self,args);
对于(var numoreries=0;numoreries
可能重复您如何唯一地识别邮件?您在消息负载中有自己的ID吗?在我的情况下(但我不是OP)-是的,消息可以通过它们的UUID来识别。唉,订阅者中只有一个简单的计数器是不够的,因为我有多个订阅者到同一队列来平衡工作,重试次数应该是全局的,而不是每个工作者的本地重试次数。这将缓存引入单点故障。我希望有一个完全使用RabbitMQ技术的解决方案。在什么情况下,您认为缓存会失败?缓存(物理)需要在任何服务器上运行。如果这台服务器坏了怎么办?因此,您需要高速缓存具有高可用性和故障安全性,这会增加所需的工作量。如果有可能使用RabbitMQ本身,我非常赞成这样一种解决方案。这肯定会引起关注,但如果您的接收器出现故障,您真的希望完全删除消息吗?将
ack
设置为true意味着需要接收消息。
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
    }
  }
}
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);
  })
})