RabbitMQ:发布服务器确认中的奇怪行为

RabbitMQ:发布服务器确认中的奇怪行为,rabbitmq,message-queue,rabbitmqctl,Rabbitmq,Message Queue,Rabbitmqctl,我是RabbitMQ新手,我使用Publisher Confirm确保消息成功传递 但是我面临一个奇怪的行为,当我发布一条消息并获取一个sequenceNumber时,函数channel.basicaks被激发n次,其中n是DeliveryTag,因此如果此消息的DeliveryTag是5,那么函数channel.basicaks被激发5次 这是我的代码: IModel channel = _customRabbitMQ.GetChannel();

我是RabbitMQ新手,我使用Publisher Confirm确保消息成功传递

但是我面临一个奇怪的行为,当我发布一条消息并获取一个sequenceNumber时,函数channel.basicaks被激发n次,其中n是DeliveryTag,因此如果此消息的DeliveryTag是5,那么函数channel.basicaks被激发5次

这是我的代码:

            IModel channel = _customRabbitMQ.GetChannel();
            IBasicProperties properties = _customRabbitMQ.GetBasicProperties();
            ulong sequenceNumber = channel.NextPublishSeqNo;

         
            message.SequenceNumber = sequenceNumber.ToString();
            _context.Messages.Update(message);
            await _context.SaveChangesAsync();

            try
            {
                _customRabbitMQ.AddOutstandingConfirm(sequenceNumber, message.Id);
                channel.BasicPublish(message.ExchangeName, message.RoutingKey, properties, Encoding.UTF8.GetBytes(JsonSerializer.Serialize(message)));
                Console.WriteLine("Message Published");
            }
            catch (Exception ex)
            {
                // TODO: log to custom logger here
                Console.WriteLine($"Error => {ex.Message}");
            }

            channel.BasicAcks += async (sender, ea) =>
            {
                try
                {
                    Console.WriteLine("Message Confirmed");

                    using var scope = _provider.CreateScope();
                    var _context = scope.ServiceProvider.GetService<Data.DataContext>();
                    var _customRabbitMQ = scope.ServiceProvider.GetService<CustomRabbitMQ>();

                    Guid messageId = _customRabbitMQ.GetOutstandingConfirm(ea.DeliveryTag);

                    Message message = await _context.Messages.Where(m => m.Id == messageId).FirstOrDefaultAsync();
                    message.Status = MessageStatuses.INQUEUE;
                    _context.Messages.Update(message);
                    await _context.SaveChangesAsync();

                    _customRabbitMQ.RemoveOutstandingConfirm(ea.DeliveryTag);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error => {ex.Message}");
                }
            };

            channel.BasicNacks += (sender, ea) =>
            {
                Console.WriteLine("Message Not Confirmed");
                _customRabbitMQ.RemoveOutstandingConfirm(ea.DeliveryTag);
            };
        }
IModel通道=_customRabbitMQ.GetChannel();
IBasicProperties=\u customRabbitMQ.GetBasicProperties();
ulong sequenceNumber=channel.NextPublishSeqNo;
message.SequenceNumber=SequenceNumber.ToString();
_context.Messages.Update(message);
wait_context.SaveChangesAsync();
尝试
{
_customRabbitMQ.AddOutstandingConfirm(sequenceNumber,message.Id);
channel.BasicPublish(message.ExchangeName、message.RoutingKey、properties、Encoding.UTF8.GetBytes(JsonSerializer.Serialize(message));
Console.WriteLine(“消息已发布”);
}
捕获(例外情况除外)
{
//TODO:在此处登录到自定义记录器
WriteLine($“Error=>{ex.Message}”);
}
channel.BasicAcks+=异步(发送方,ea)=>
{
尝试
{
Console.WriteLine(“消息已确认”);
使用var scope=_provider.CreateScope();
var_context=scope.ServiceProvider.GetService();
var_customRabbitMQ=scope.ServiceProvider.GetService();
Guid messageId=\u customRabbitMQ.GetOutstandingConfirm(ea.DeliveryTag);
Message Message=wait_context.Messages.Where(m=>m.Id==messageId).FirstOrDefaultAsync();
message.Status=MessageStatuses.INQUEUE;
_context.Messages.Update(message);
wait_context.SaveChangesAsync();
_customRabbitMQ.RemoveOutstandingConfirm(ea.DeliveryTag);
}
捕获(例外情况除外)
{
WriteLine($“Error=>{ex.Message}”);
}
};
channel.BasicNacks+=(发送方,ea)=>
{
Console.WriteLine(“消息未确认”);
_customRabbitMQ.RemoveOutstandingConfirm(ea.DeliveryTag);
};
}
那么,为什么会发生这种情况,如何阻止它,并使它只确认一次


提前感谢。

我认为问题在于每次发布消息时都要初始化侦听器。
因此,当您发布带有
DT=1
的消息时,您可以通过添加
channel.BasicAck+=fun
来创建一个侦听器,当添加带有
DT=2
的消息时,您可以创建另一个侦听器,因此当DT_2上的确认返回时,它将被推送到两个侦听器,这就解释了为什么你会收到一个带有相同号码的送货标签的确认。

我还不完全清楚这个问题,但可能选项
multiple
会有所帮助,实际上,“multiple”标志总是“false”,但是函数调用了多次。