Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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?

I have tried using

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

my complete code is

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;
        }
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
456 views
Welcome To Ask or Share your Answers For Others

1 Answer

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.

Here is the diagram: enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...