Priority and dead letter queue of RabbitMQ and. net core messages

Posted by andrew_ww on Sat, 18 Apr 2020 17:28:20 +0200

1. Priority of message

If there is a requirement now, we need to push some of the highest priority notifications to the client. We can use the sortedset of redis or the message priority attribute of rabbit we are going to talk about today

Producer code

using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace RabbitMQConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "39.**.**.**";
            factory.Port = 5672;
            factory.VirtualHost = "/";
            factory.UserName = "root";
            factory.Password = "root";

            var exchange = "change4";
            var route = "route2";
            var queue9 = "queue9";

            using (var connection = factory.CreateConnection())
            {
                using (var channel = connection.CreateModel())
                {
                    channel.ExchangeDeclare(exchange, type: "fanout", durable: true, autoDelete: false);
            //x-max-priority Property must be set, otherwise message priority will not take effect
                    channel.QueueDeclare(queue9, durable: true, exclusive: false, autoDelete: false,arguments: new Dictionary<string, object> { { "x-max-priority", 50 } });
                    channel.QueueBind(queue9, exchange, queue9);
                    while(true)
                    {
                        var messagestr = Console.ReadLine();
                        var messagepri = Console.ReadLine();
                        var props = channel.CreateBasicProperties();
                        props.Persistent = true;
                        props.Priority = (byte)int.Parse(messagepri);//Set message priority
                        channel.BasicPublish(exchange, route, true, props, Encoding.UTF8.GetBytes(messagestr));
                    }
                }
            }
        }
    }
}

consumer code

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace RabbitMQClient
{
    class Program
    {
        private static readonly ConnectionFactory rabbitMqFactory = new ConnectionFactory()
        {
            HostName = "39.**.**.**",
            Port = 5672,
            UserName = "root",
            Password = "root",
            VirtualHost = "/"
        };
        static void Main(string[] args)
        {
            var exchange = "change4";
            var route = "route2";
            var queue9 = "queue9";


            using (IConnection conn = rabbitMqFactory.CreateConnection())
            using (IModel channel = conn.CreateModel())
            {
                channel.ExchangeDeclare(exchange, "fanout", durable: true, autoDelete: false);
                channel.QueueDeclare(queue9, durable: true, exclusive: false, autoDelete: false, arguments: new Dictionary<string, object> { { "x-max-priority", 50 } });
                channel.QueueBind(queue9, exchange, route);

                channel.BasicQos(prefetchSize: 0, prefetchCount: 50, global: false);
                EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    Byte[] body = ea.Body;
                    String message = Encoding.UTF8.GetString(body);
                    Console.WriteLine( message);
                    channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
                };

                channel.BasicConsume(queue: queue9, autoAck: false, consumer: consumer);
                Console.ReadLine();
            }
        }
    }
}

Run producer

consumer is running

You can see that messages are consumed by priority

2. Dead letter queue

The dead letter queue can be used as a fault tolerance mechanism. When our message processing is abnormal, we can put the message into the dead letter queue for later processing. There are three kinds of dead letter generation

1. The message is rejected (basic.reject or basic.nack) and not rejoined (request = false);

2. The number of messages in the current queue has exceeded the maximum length.

3. The message expires in the queue, that is, the current message's lifetime in the queue has exceeded the preset TTL(Time To Live) time;

Look at code

using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace RabbitMQConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "39.**.**.**";
            factory.Port = 5672;
            factory.VirtualHost = "/";
            factory.UserName = "root";
            factory.Password = "root";

            var exchangeA = "changeA";
            var routeA = "routeA";
            var queueA = "queueA";

            var exchangeD = "changeD";
            var routeD = "routeD";
            var queueD = "queueD";

            using (var connection = factory.CreateConnection())
            {
                using (var channel = connection.CreateModel())
                {
                    channel.ExchangeDeclare(exchangeD, type: "fanout", durable: true, autoDelete: false);
                    channel.QueueDeclare(queueD, durable: true, exclusive: false, autoDelete: false);
                    channel.QueueBind(queueD, exchangeD, routeD);

                    channel.ExchangeDeclare(exchangeA, type: "fanout", durable: true, autoDelete: false);
                    channel.QueueDeclare(queueA, durable: true, exclusive: false, autoDelete: false, arguments: new Dictionary<string, object> {
                                         { "x-dead-letter-exchange",exchangeD}, //Set the DLX
                                         { "x-dead-letter-routing-key",routeD}, //Set up DLX Routing key,DLX According to this value, the queue in which the dead letter message is stored will be found
                                         { "x-message-ttl",10000} //Set message lifetime, i.e. expiration time
                                         });
                    channel.QueueBind(queueA, exchangeA, routeA);


                    var properties = channel.CreateBasicProperties();
                    properties.Persistent = true;
                    //Publish news
                    channel.BasicPublish(exchange: exchangeA,
                                         routingKey: routeA,
                                         basicProperties: properties,
                                         body: Encoding.UTF8.GetBytes("message"));
                }
            }
        }
    }
}

After 10 seconds, the message expires. We can see that there is a message in queueD


Source: https://www.cnblogs.com/chenyishi/p/10242162.html

Topics: RabbitMQ encoding Redis Attribute