在手动确认模式(带noAck=false
)中,可以在接收和处理消息后确认消息。使用IBasicConsumer
时,.NET/C# API Guide表示可以在消费消息时逐个完成此操作:
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (_, e) =>
{
// process the message...
channel.BasicAck(e.DeliveryTag, false);
};
string consumerTag = channel.BasicConsume(queueName, false, consumer);
但是,在我的特定场景中,我需要先消耗几个消息,然后才能处理它们。并且,为了保持持久性,我将不得不稍后确认以前的消息(在收到它们的范围之外)。这些确认也可能以不同的顺序与收到邮件的顺序发生。
var consumer = new EventingBasicConsumer(channel);
var buffer = new List<BasicDeliverEventArgs>();
consumer.Received += (_, e) =>
{
buffer.Add(e);
if (TryProcess(buffer, out IList<BasicDeliverEventArgs> subset))
{
foreach (var p in subset)
{
channel.BasicAck(p.DeliveryTag, false);
buffer.Remove(p);
}
}
};
string consumerTag = channel.BasicConsume(queueName, false, consumer);
当我尝试这个时,我只收到一些消息,然后是块,这让我觉得RabbitMQ不支持这个。我还使用频道的BasicQos
方法将prefetchCount
提升到数百,但我收到的邮件数量仍然只有4或5。
RabbitMQ是否支持无序递送确认?如果没有,是否有更好的技术我可以使用RabbitMQ提供相同的耐久性?