Node.js 节点amqp-尝试X次后拒绝消息
如何实现在几次可配置的重新请求尝试后拒绝消息的机制 换句话说,如果我订阅了一个队列,我想保证相同的消息不会被重新传递超过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); } } 一种可能的解决方案是使用您定义的某种散列函数对消息进行散列,然
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);
})
})