重新排队后保持交付顺序

3
我正在开发一个使用Rabbit MQ的消息应用程序。我使用显式ACK:
model.BasicConsume(queueName,false, consumer);

在处理消息后执行ACK:

consumer.Received += (ch, ea) =>
                {
                    try
                    {                        
                        var message = Encoding.UTF8.GetString(ea.Body);

                        Logger.Info($"DeliveryTag={ea.DeliveryTag}, message={message}");

                        ((EventingBasicConsumer)ch).Model.BasicAck(ea.DeliveryTag, false);

                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                        throw;
                    }
                };

当处理消息出现错误并且RabbitMQ没有收到ACK时,它会将消息以不同的顺序返回到队列中。例如,有消息M1、M2、M3、M4,如果M2被发送回队列,则顺序变成了M3、M4、M2。是否有任何方法可以保持交付顺序?注意:我只有一个消费者和RabbitMQ 3.6.6,但我仍然遇到重新排序的问题。
1个回答

3

关于消息排序保证的内容,这里已经有详细的解释。以下是摘录:

可以通过具有requeue参数的AMQP方法(basic.recover、basic.reject和basic.nack)将消息返回到队列中, 或者在持有未确认消息时关闭通道,任何这些情况都会导致消息重新排队到队列的末尾, 对于2.7.0之前的RabbitMQ版本都是如此。从RabbitMQ 2.7.0开始,无论是否重新排队或通道关闭, 消息始终按发布顺序保留在队列中。

从2.7.0版本开始,即使存在重新排队或通道关闭, 队列仍然始终按发布顺序保留消息。但如果队列有多个订阅者,则仍然可能会出现单独消费者观察到乱序的消息, 这是由于其他订阅者重新排队消息的影响。从队列的角度来看,消息始终按发布顺序保留。


是的,正如我所写的:“我只有一个消费者和RabbitMQ 3.6.6,但我仍然有重新排序的问题”。 - Timur Lemeshko
你解决了吗?我们也遇到了同样的问题。我们希望一个失败的消息能够一直停留在队列的前面,防止其他消息被处理,直到该消息得到解决。 - user2047485

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接