Rabbitmq Ack 或 Nack,将消息留在队列中

Rabbitmq Ack or Nack, leaving messages on the queue(Rabbitmq Ack 或 Nack,将消息留在队列中)
本文介绍了Rabbitmq Ack 或 Nack,将消息留在队列中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在玩 RabbitMq.net 和消息确认.如果消费者能够处理消息,您可以以

I have been playing around with RabbitMq.net and the message acknowledgements. If the consumer is able to process the message you can send back an ack in the form of

channel.BasicAck(ea.DeliveryTag, false);

这会将它从队列中移除.

which will take it off the queue.

但是如果消息无法处理怎么办?可能是临时中断,您不希望将消息从队列中删除,然后将其放在后面并继续下一条消息?

But what about if the message was unable to be processed ? maybe a temporary outage and you don't want the message taken off the queue just put to the back and carry on with the next message?

我尝试过使用

channel.BasicNack(ea.DeliveryTag, false, true);

但下一轮它仍然会收到相同的消息,并且不会移动到队列中的下一条消息

but the next time round its still getting the same message and not moving to the next message in the queue

我的完整代码是

class Program
{
    private static IModel channel;
    private static QueueingBasicConsumer consumer;
    private static IConnection Connection;

    static void Main(string[] args)
    {
        Connection = GetRabbitMqConnection();
        channel = Connection.CreateModel();
        channel.BasicQos(0, 1, false);
        consumer = new QueueingBasicConsumer(channel);
        channel.BasicConsume("SMSQueue", false, consumer);
        while (true)
        {
            if (!channel.IsOpen)
            {
                throw new Exception("Channel is closed");
            }
            var ea = consumer.Queue.Dequeue();
            string jsonified = Encoding.UTF8.GetString(ea.Body);
            var message = JsonConvert.DeserializeObject<SmsRecords>(jsonified);
            if (ProcessMessage())
                channel.BasicAck(ea.DeliveryTag, false);
            else
                channel.BasicNack(ea.DeliveryTag, false, true);
        }
    }

    private static bool ProcessMessage()
    {
        return false;
    }

    public static IConnection GetRabbitMqConnection()
    {
        try
        {
            var connectionFactory = new ConnectionFactory
            {
                UserName = "guest",
                Password = "guest",
                HostName = "localhost"
            };
            return connectionFactory.CreateConnection();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return null;
        }
    }
}

推荐答案

我的公司是这样做的:如果一条消息失败(出于任何原因),我们将消息放入一个等待队列中等待 10 秒,它然后被放回队列中重试.我们最多循环 10 次,如果消息被 nack 10 次,那么我们认为这是一个我们无法恢复的失败,我们将它放入一个永久的死信队列进行调查.

This is how my company does it: If a message fails (for any reason) we nack the message into a holding queue where it sits for 10 seconds, it then gets put back into the queue to be retried. We do this loop up to 10 times, if the message is nacked 10 times then we assume it is a failure we can't recover from and we put it into a permanent dead-letter queue for investigation.

图表如下:

这篇关于Rabbitmq Ack 或 Nack,将消息留在队列中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)