RabbitMQ与.net core(四) 消息的优先级 与 死信队列

1.消息的优先级

假如现在有个需求,我们需要让一些优先级最高的通知推送到客户端,我们可以使用redis的sortedset,也可以使用我们今天要说的rabbit的消息优先级属性

Producer代码

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属性必须设置,否则消息优先级不生效
                    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);//设置消息优先级
                        channel.BasicPublish(exchange, route, true, props, Encoding.UTF8.GetBytes(messagestr));
                    }
                }
            }
        }
    }
}

consumer代码

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();
            }
        }
    }
}

运行producer

在运行consumer

可以看出消息是按优先级消费的

2.死信队列

死信队列可以用来做容错机制,当我们的消息处理异常时我们可以把消息放入到死信队列中,以便后期处理,死信的产生有三种

1.消息被拒(basic.reject or basic.nack)并且没有重新入队(requeue=false);

2.当前队列中的消息数量已经超过最大长度。

3.消息在队列中过期,即当前消息在队列中的存活时间已经超过了预先设置的TTL(Time To Live)时间;

看代码

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}, //设置当前队列的DLX
                                         { "x-dead-letter-routing-key",routeD}, //设置DLX的路由key,DLX会根据该值去找到死信消息存放的队列
                                         { "x-message-ttl",10000} //设置消息的存活时间,即过期时间
                                         });
                    channel.QueueBind(queueA, exchangeA, routeA);

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

这样10秒后消息过期,我们可以看到queueD中有了消息

原文地址:https://www.cnblogs.com/chenyishi/p/10242162.html

时间: 2024-10-30 23:18:07

RabbitMQ与.net core(四) 消息的优先级 与 死信队列的相关文章

RabbitMQ实战-死信队列

RabbitMQ死信队列 场景说明 代码实现 简单的Util 生产者 消费者 场景说明 场景: 当队列的消息未正常被消费时,如何解决? 消息被拒绝并且不再重新投递 消息超过有效期 队列超载 方案: 未被消费的消息,可通过"死信队列"重新被消费 死信队列含义,发生以上情况时,该队列上的消息,可通过配置转发到死信队列,被重新消费 模拟实现: 1个生产者,2个交换机和队列(普通和死信),1个消费者(死信消费者) 通过消息超时,模拟未正常消费场景 启动死信队列消费者,等待消息... 启动生产者

RabbitMQ死信队列

死信队列DLX,全称为Dead-Letter Exchange,可以称之为死信交换器,也有人称之为死信邮箱.当消息在一个队列中变成死信(dead message)之后,它能被重新被发送到另一个交换器中,这个交换器就是DLX,绑定DLX的队列就称之为死信队列.消息变成死信-般是由于以下几种情况:1.消息被拒绝(basic.reject或basic.nack)并且requeue=false.2.消息TTL过期[消息由于消息有效期(per-message TTL)过期]3.队列达到最大长度(队列满了,

RabbitMQ学习系列(四): 几种Exchange 模式

上一篇,讲了RabbitMQ的具体用法,可以看看这篇文章:RabbitMQ学习系列(三): C# 如何使用 RabbitMQ.今天说些理论的东西,Exchange 的几种模式. AMQP协议中的核心思想就是生产者和消费者隔离,生产者从不直接将消息发送给队列.生产者通常不知道是否一个消息会被发送到队列中,只是将消息发送到一个交换机.先由Exchange来接收,然后Exchange按照特定的策略转发到Queue进行存储.同理,消费者也是如此.Exchange 就类似于一个交换机,转发各个消息分发到相

RabbitMQ与.net core(二)Producer与Exchange

原文:RabbitMQ与.net core(二)Producer与Exchange Producer:消息的生产者,也就是创建消息的对象 Exchange:消息的接受者,也就是用来接收消息的对象,Exchange接收到消息后将消息按照规则发送到与他绑定的Queue中.下面我们来定义一个Producer与Exchange. 1.新建.netcore console项目,并引入RabbitMQ.Client的Nuget包 2.创建Exchange using RabbitMQ.Client; nam

RabbitMQ入门教程(十一):消息属性Properties

原文:RabbitMQ入门教程(十一):消息属性Properties 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/vbirdbest/article/details/78698364 分享一个朋友的人工智能教程.比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看. 简介 发送消息可以为消息指定一些参数 Delivery mode: 是否持久化,1 - Non-persistent,2 -

RabbitMQ入门教程(十四):RabbitMQ单机集群搭建

原文:RabbitMQ入门教程(十四):RabbitMQ单机集群搭建 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/vbirdbest/article/details/78723467 分享一个朋友的人工智能教程.比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看. 集群简介 理解集群先理解一下元数据 队列元数据:队列的名称和声明队列时设置的属性(是否持久化.是否自动删除.队列所属的节点)

RabbitMQ系列二(构建消息队列)

从AMQP协议可以看出,MessageQueue.Exchange和Binding构成了AMQP协议的核心.下面我们就围绕这三个主要组件,从应用使用的角度全面的介绍如何利用RabbitMQ构建消息队列以及使用过程中的注意事项. 声明MessageQueue: 在RabbitMQ中,无论是生产者发送消息还是消费者接收消息,都首先需要声明一个MessageQueue.这就存在一个问题,是生产者声明还是消费者声明呢?要解决这个问题,首先要明确: 1)消费者是无法订阅或者获取不存在的MessageQue

RabbitMQ系列三 (深入消息队列)

消息持久化是 RabbitMQ 最为人津津乐道的特性之一, RabbitMQ 能够在付出最小的性能代价的基础上实现消息的持久化,最大的奥秘就在于 RabbitMQ 多层消息队列的设计上.下面,本文就从 MessageQueue 的设计和消息在 MessageQueue 的生命周期两个方面全面介绍  RabbitMQ 的消息队列. RabbitMQ完全实现了AMQP协议,类似于一个邮箱服务.Exchange负责根据ExchangeType和RoutingKey将消息投递到对应的消息队列中,消息队列

RabbitMQ与.net core(一)安装

原文:RabbitMQ与.net core(一)安装 一.安装Erlang环境 前提:erlang版本与rabbitmq版本需按照要求对应!!! 1.在安装erlang之前先安装下依赖文件(这一步不要忘掉了, 不然后面./configure的时候要报错): [[email protected] local]# yum install gcc glibc-devel make ncurses-devel openssl-devel xmlto 2.到erlang官网去下载erlang安装包 官网地