.NET Core 消息队列的使用

一、消息队列的优点

消息队列本质是生产者——消费者模式。也有很多使用方式。那么它有什么优点呢?以日常生活中邮寄信件这个行为举例, 当只有1个寄信人,1个邮递员的时候。寄信人想要寄信,到指定地点(邮局),直接将信件交给邮递员即可。

510a26bad731ba0d084b880e3ca8d3cd.png

当有50个寄信人的时候,1个邮递员的时候。这50个寄信人就要依次排队等待邮递员处理信件。可以增加邮递员的数量,但是依然会有忙闲不均的问题存在。

5877aeb4361efe47ef15054d626f7667.png

我们现在增加一个邮筒(也就是数据缓冲区)

a6054a4f42a9f55ee038a573208fbb7d.png

在这个例子中,寄信人就是生产者,邮递员是消费者。而邮筒就是一个消息队列。这个邮筒解决了以下问题:

1.1 解除耦合

实现了时间上解耦,也实现了对象间解耦。之前邮递员隶属于A邮局,寄信人想要寄信,到指定地点,直接将信件交给邮递员即可。如果因为实际需求,以后由B邮局的快递员负责寄信业务。那么寄信人就要去另一个地点寄信。这就是由于耦合产生的问题。现在不管信件是由A邮局还是其他邮局负责,寄信人只管将信件投递进邮筒就行了。解除了寄信人和邮递员的耦合性。

1.2 实现异步处理

之前寄信将信件直接交给邮递员,可能要等待邮递员要确认很多信息(比如寄件人信息)之后,长辄几分钟,才能结束本次寄信的行为。而现在将信件直接投递到邮箱里,只要不到1S,就能结束寄信的行为。

1.3 支持并发操作

解决同步处理的阻塞问题。之前所有寄信人需要排队等待上一个人寄信完毕,才能开始寄信。现在所有寄信人都把信件投递进邮筒即可。

1.4 实现流量削峰

可以根据邮递员方的处理能力,调节邮筒的容量。超过这个容量后,邮筒就放不下(拒绝)信件了。即能根据下游的处理能力自由调节流量,实现削峰。

二、安装erlang和RabbitMQ

2.1 安装erlang

由于RabbitMQ是基于erlang开发的,需要先安装erlang。确认自己要安装的RabbitMQ依赖的erlang的最低版本。

erlang:https://www.erlang.org/downloads 

安装后添加环境变量。

在系统变量中添加:

变量名:ERLANG_HOME

变量值:C:\Program Files\erl-24.0(安装ERLANG的文件夹) 

然后在用户变量的PATH中添加:%ERLANG_HOME%\bin

添加完环境变量之后可能需要重启。

然后打开CMD,运行erl,出现版本号为成功。

bcd1754e62ca9353cf99134698f56bc7.png

2.2 安装RabbitMQ

RabbitMQ:https://github.com/rabbitmq/rabbitmq-server/releases/ 

安装成功后会自动创建RabbitMQ服务并且启动 

可以在任务管理器中确认:

df2099047aed680f5afeb71b7989c24f.png

2.3 安装RabbitMQ的Web管理插件

在命令行中CD到安装目录下,执行 

rabbitmq-plugins.bat enable rabbitmq_management

0833a012309ae103a049ebcea79fcdca.png

成功后进入浏览器,输入:http://localhost:15672

初始账号和密码:guest/guest

b1cb5bbad295faf502d628d42eba4cd8.png

三、理解消息队列中的基本概念

消息队列中有Exchange、Connection、Channel、Queue等概念

3.1 Exchange(交换机)

是生产者和消息队列的一个中介,负责将生产者的消息分发给消息队列。如果使用简单模式(只有一个生产者,一个消费者,一对一)时,不配置Exchange,实际上使用的是默认的Exchange。

3.2 Connection(连接)

是连接到MQ的TCP连接。为了方便理解,可以将Connection想象成一个光纤电缆。

3.3 Channel(通道)

一个Connection中存在多个Channel。可以把Channel理解为光纤电缆中的光纤。

3.4 Queue(消息队列)

一个Channel中可以存在多个Queue。

3.5 其他

因为建立和销毁 TCP 连接是非常昂贵的开销,所以一般维持Connection。在Connection之上,操作channel。Channel的其中一个作用就是,屏蔽Connection的TCP层面的细节,方便开发,同时达到TCP连接复用的效果。

四、尝试消息队列的简单模式(一对一)

新建一个解决方案,包含两个控制台程序,分别是生产者和消费者。右键解决方案,设置多项目启动。

0c41057e0d60f46c4ef454da60c58fcb.png

4.1 生产者代码

/// <summary>
    /// 生产者
    /// </summary>
    internal class Program
    {
        private static void Main(string[] args)
        {
            //创建连接工厂
            ConnectionFactory factory = new ConnectionFactory
            {
                UserName = "guest",//用户名
                Password = "guest",//密码
                HostName = "localhost"//rabbitmq ip
            };

            //创建RabbitMQ的TCP长连接(可以比喻成一个光纤电缆)
            //因为建立和销毁 TCP 连接是非常昂贵的开销,所以一般维持连接(TCP连接复用)。在连接之上,建立和销毁channel。
            var connection = factory.CreateConnection();

            //创建通道(可以比喻成光纤电缆中的"一根"光纤)
            var channel = connection.CreateModel();

            /*声明一个队列:实现通道与队列的绑定
             * 5个参数:
             * queue:被绑定的消息队列名,当该消息队列不存在时,将新建该消息队列
             * durable:是否使用持久化
             * exclusive:该通道是否独占该队列
             * autoDelete:消费完成时是否删除队列, 该删除操作在消费者彻底断开连接之后进行。
             * args:其他配置参数
             */
            channel.QueueDeclare("hello", false, false, false, null);

            Console.WriteLine("\nRabbitMQ连接成功,生产者已启动,请输入消息,输入exit退出!");

            string input;
            do
            {
                input = Console.ReadLine();
                var sendBytes = Encoding.UTF8.GetBytes(input);
                //发布消息
                channel.BasicPublish("", "hello", null, sendBytes);
            }
            while (input.Trim().ToLower() != "exit");

            channel.Close();
            connection.Close();
        }
    }

4.2 消费者代码

/// <summary>
    /// 消费者
    /// </summary>
    internal class Program
    {
        private static void Main(string[] args)
        {
            //创建连接工厂
            ConnectionFactory factory = new ConnectionFactory
            {
                UserName = "guest",//用户名
                Password = "guest",//密码
                HostName = "localhost"//rabbitmq ip
            };

            //创建连接
            var connection = factory.CreateConnection();

            //创建通道
            var channel = connection.CreateModel();

            //事件基本消费者
            EventingBasicConsumer consumer = new EventingBasicConsumer(channel);

            //接收到消息事件
            consumer.Received += (ch, ea) =>
            {
                string message = Encoding.Default.GetString(ea.Body.ToArray());

                Console.WriteLine($"收到消息: {message}");

                //确认该消息已被消费
                channel.BasicAck(ea.DeliveryTag, false);

            };

            //启动消费者 设置为手动应答消息
            channel.BasicConsume("hello", false, consumer);
            Console.WriteLine("消费者已启动");
            Console.ReadKey();
            channel.Dispose();
            connection.Close();
        }
    }

4.3 测试

两个项目一起启动之后 在生产者对应的控制台输入文字后,添加到消息队列中,由消费者进行消费,显示在消费者控制台上。

8be212d94ff0ceead7935d95befa3999.png

转自:SoraXTube.com✨

链接:cnblogs.com/soraxtube/p/14789116.html

- EOF -

技术群:添加小编微信dotnet999

公众号:dotnet讲堂

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是使用 RabbitMQ 消息队列.NET Core Demo: 首先,需要创建一个 .NET Core Console 应用程序。在控制台中,使用以下命令: ``` dotnet new console -o RabbitMQDemo cd RabbitMQDemo ``` 接着,需要安装 RabbitMQ 客户端库:RabbitMQ.Client。使用以下命令: ``` dotnet add package RabbitMQ.Client ``` 在代码中,我们可以使用以下代码来连接到 RabbitMQ,并向队列发送消息: ```csharp using RabbitMQ.Client; using System; using System.Text; class Program { static void Main(string[] args) { var factory = new ConnectionFactory() { HostName = "localhost" }; using (var connection = factory.CreateConnection()) using (var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null); string message = "Hello World!"; var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "", routingKey: "hello", basicProperties: null, body: body); Console.WriteLine(" [x] Sent {0}", message); } Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } ``` 在上面的代码中,我们使用了 ConnectionFactory 类来创建一个连接到 RabbitMQ 的连接。然后,我们使用连接创建一个 channel,并使用 channel.QueueDeclare() 方法来声明一个名为 "hello" 的队列。 接着,我们将要发送的消息编码成字节数组,并使用 channel.BasicPublish() 方法将消息发布到队列中。 最后,我们使用 Console.ReadLine() 方法来等待用户按下回车键,以便程序可以安全地退出。 在另一个控制台中,我们可以使用以下代码来接收队列中的消息: ```csharp using RabbitMQ.Client; using RabbitMQ.Client.Events; using System; using System.Text; class Program { static void Main(string[] args) { var factory = new ConnectionFactory() { HostName = "localhost" }; using (var connection = factory.CreateConnection()) using (var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body.ToArray(); var message = Encoding.UTF8.GetString(body); Console.WriteLine(" [x] Received {0}", message); }; channel.BasicConsume(queue: "hello", autoAck: true, consumer: consumer); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } } ``` 在上面的代码中,我们同样使用 ConnectionFactory 创建连接和 channel。然后,我们使用 channel.QueueDeclare() 方法声明名为 "hello" 的队列。 接着,我们使用 EventingBasicConsumer 类创建一个消费者,并在 Received 事件处理程序中输出收到的消息。 最后,我们使用 channel.BasicConsume() 方法开始消费队列中的消息,并使用 Console.ReadLine() 方法等待用户按下回车键以退出程序。 这就是使用 RabbitMQ 客户端库的 .NET Core 消息队列 Demo。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值