服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - 如何用.NETCore操作RabbitMQ

如何用.NETCore操作RabbitMQ

2022-11-17 13:34青城同学 C#

这篇文章主要介绍了如何用.NETCore操作RabbitMQ,对中间件感兴趣的同学,可以参考下

什么是RabbitMQ?

如何用.NETCore操作RabbitMQ

RabbitMQ是由erlang语言开发的一个基于AMQP(Advanced Message Queuing Protocol)协议的企业级消息队列中间件。可实现队列,订阅/发布,路由,通配符等工作模式。

 

为什么要使用RabbitMQ?

  • 异步处理:比如发送邮件,发送短信等不需要等待处理结果的操作
  • 应用解耦:比如下单成功后,通知仓库发货,不需要等待仓库回应,通过消息队列去通知仓库,降低应用间耦合程序,可并行开发两个功能模块
  • 流量削锋:在抢购或者其他的活动页,服务处于爆发式请求状态,如果直连数据库,数据库容易被拖垮。抢购商品也容易出现库存超卖的情况。通过队列可有效解决该问题。
  • 日志处理:在单机中,日志直接写入到文件目录中,但是在分布式应用中,日志需要有统一的处理机制,可通过消息队列统一由某个消费端做处理。
  • 消息通信:如生产端和消费端可通过队列进行异步通信

 

如何安装RabbitMQ?

Windows端

1.安装erlang语言运行环境
https://erlang.org/download/otp_win64_23.2.exe
下载后直接下一步即可

2.安装RabbitMQ
https://www.rabbitmq.com/install-windows.html
直接点击安装下一步即可按章

3.安装RabbitMQ的Web管理平台

RabbitMQ的管理平台是通过插件的形式使用,需要手动启用管理平台
在Windows下,RabbitMQ默认被安装到C:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.14 下。
打开sbin ,在cmd或者powershell中执行

rabbitmq-plugins.bat enable rabbitmq_management

安装完成后,浏览器打开 http://localhost:15672/ 即可看到RabbitMQ的管理界面。输入默认账号密码 guest 成功登录。

Linux环境安装

1.Ubuntu:https://www.rabbitmq.com/install-debian.html

2.Centos:https://www.rabbitmq.com/install-rpm.html

 

RabbitMQ的基本概念

生产者

发送消息的端

消费者

获取消息并处理的端

Connection

一个终端连接。每一个Connection都可以在RabbitMQ后台看到

如何用.NETCore操作RabbitMQ

Channel

Channel是建立在Connection上的一个虚拟通信管道。一般情况下,往消息队列中写入多条消息,为了不每条消息都建立一个TCP连接,所以RabbitMQ的做法是多条消息可以公用一个Connection,大大提高MQ的负载能力。

Exchange

Exchange是一个虚拟交换机。每一条消息都必须要通过交换机才能能进入对应的队列,可以理解为网络设备中的交换机,是一个意思。

Queue

Queue是一个存储消息的内部对象,所有的Rabbit MQ消息都存储在Queue中。生产者所生产的消息会存储在Queue中,消费者获取的消息也是从Queue中获取。

 

如何在.NET Core中使用RabbitMQ?

nuget安装

dotnet add package RabbitMQ.Client

创建生产者

const string QUEUENAME = "HELLO_MQ";
//创建连接对象工厂
var factory = new ConnectionFactory()
{
  UserName = "guest",
  Password = "guest",
  HostName = "localhost",
  Port = 5672,  //RabbitMQ默认的端口
};

while (true)
{
  using var conn = factory.CreateConnection();
  var chanel = conn.CreateModel();

  chanel.QueueDeclare(QUEUENAME, true, false, false);
  Console.WriteLine("输入生产内容:");
  var input = Console.ReadLine();
  chanel.BasicPublish("", QUEUENAME, null, Encoding.Default.GetBytes("hello rabbitmq:" + input));
}

在循环中,输入一个值,按下enter,即可推送一条消息到队列。

也可以直接在RabbitMQ的管理后台查看

如何用.NETCore操作RabbitMQ

如何用.NETCore操作RabbitMQ

如何用.NETCore操作RabbitMQ

可以看到我们发送的消息已经被RabbitMQ存储在Queue中了。只等某个幸运的消费者前来消费。

创建消费者

const string QUEUENAME = "HELLO_MQ";
var factory = new ConnectionFactory()
{
  UserName = "guest",
  Password = "guest",
  HostName = "localhost",
  Port = 5672,
};

var conn = factory.CreateConnection();
var chanel = conn.CreateModel();
chanel.QueueDeclare(QUEUENAME, true, false, false);
EventingBasicConsumer consumer = new EventingBasicConsumer(chanel);
consumer.Received += (a, e) =>
{
  Console.WriteLine($"{DateTime.Now.ToString()}接收到消息:" + Encoding.Default.GetString(e.Body.ToArray()));
  chanel.BasicAck(e.DeliveryTag, true); //收到回复后,RabbitMQ会直接在队列中删除这条消息
};
chanel.BasicConsume(QUEUENAME, false, consumer);

Console.WriteLine("启动成功");
Console.ReadLine();

启动成功后,consumer的Received方法,会收到一条来自MQ的消息,

如何用.NETCore操作RabbitMQ

如果处理完成后,不调用chennel的BasicAck方法,那么这条消息依然会存在,下次有消费者出现,会再次推送给消费者。

简单的RabbitMQ Hello World到这里就算完成了。接下来就是稍微高级一点的应用

 

RabbitMQ的工作模式

Work Queue 工作队列模式

如何用.NETCore操作RabbitMQ

工作队列模式的意思就是一个生产者对应多个消费者。RabbitMQ会使用轮询去给每个消费者发送消息。

publish/subscribe

发布订阅模式是属于比较用多的一种。

如何用.NETCore操作RabbitMQ

发布订阅,是由交换机发布消息给多个队列。多个队列再对应多个消费者。

发布订阅模式对应的交换机类型的fanout。

消费者

A

const string QUEUENAME = "HELLO_MQ_B";
const string TESTEXCHANGE = "TESTEXCHANGE";
var factory = new ConnectionFactory()
{
  UserName = "guest",
  Password = "guest",
  HostName = "localhost",
  Port = 5672,
};

var conn = factory.CreateConnection();
var channel = conn.CreateModel();
//定义队列
channel.QueueDeclare(QUEUENAME, true, false, false);
//定义交换机
channel.ExchangeDeclare(TESTEXCHANGE, ExchangeType.Fanout, true, false);
//绑定队列到交换机
channel.QueueBind(QUEUENAME, TESTEXCHANGE, "");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (a, e) =>
{
  Console.WriteLine($"{DateTime.Now.ToString()}接收到消息:" + Encoding.Default.GetString(e.Body.ToArray()));
  channel.BasicAck(e.DeliveryTag, true); //收到回复后,RabbitMQ会直接在队列中删除这条消息
};
channel.BasicConsume(QUEUENAME, false, consumer);

Console.WriteLine("启动成功");
Console.ReadLine();

B

const string QUEUENAME = "HELLO_MQ";
const string TESTEXCHANGE = "TESTEXCHANGE";
var factory = new ConnectionFactory()
{
  UserName = "guest",
  Password = "guest",
  HostName = "localhost",
  Port = 5672,
};

var conn = factory.CreateConnection();
var channel = conn.CreateModel();
//定义队列
channel.QueueDeclare(QUEUENAME, true, false, false);
//定义交换机
channel.ExchangeDeclare(TESTEXCHANGE, ExchangeType.Fanout, true, false);
//绑定队列到交换机
channel.QueueBind(QUEUENAME, TESTEXCHANGE, "");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (a, e) =>
{
  Console.WriteLine($"{DateTime.Now.ToString()}接收到消息:" + Encoding.Default.GetString(e.Body.ToArray()));
  channel.BasicAck(e.DeliveryTag, true); //收到回复后,RabbitMQ会直接在队列中删除这条消息
};
channel.BasicConsume(QUEUENAME, false, consumer);

Console.WriteLine("启动成功");
Console.ReadLine();

生产者

const string QUEUENAME = "HELLO_MQ";
const string QUEUENAME_B = "HELLO_MQ_B";
const string TESTEXCHANGE = "TESTEXCHANGE";

//创建连接对象工厂
var factory = new ConnectionFactory()
{
  UserName = "guest",
  Password = "guest",
  HostName = "localhost",
  Port = 5672,  //RabbitMQ默认的端口
};
using var conn = factory.CreateConnection();
while (true)
{

  var channel = conn.CreateModel();
  //定义交换机
  channel.ExchangeDeclare(TESTEXCHANGE, ExchangeType.Fanout, true, false);
  Console.WriteLine("输入生产内容:");
  var input = Console.ReadLine();
  channel.BasicPublish(TESTEXCHANGE,"", null, Encoding.Default.GetBytes("hello rabbitmq:" + input));
}

在生产者运行成功后,RabbitMQ后台会出现一个交换机,点击交换机会看到交换机下绑定了两个队列

如何用.NETCore操作RabbitMQ

如何用.NETCore操作RabbitMQ

从生产者发送消息到队列,两个消费者会同时收到消息

如何用.NETCore操作RabbitMQ

routing模式

如何用.NETCore操作RabbitMQ

routing模式对应的交换机类型是direct,和发布订阅模式的区别在于:routing模式下,可以指定一个routingkey,用于区分消息

生产者

var channel = conn.CreateModel();
//定义交换机
channel.ExchangeDeclare(TESTEXCHANGE, ExchangeType.Direct, true, false);
//绑定队列到交换机
Console.WriteLine("输入生产内容:");
var input = Console.ReadLine();
channel.BasicPublish(TESTEXCHANGE, "INFO", null, Encoding.Default.GetBytes("hello rabbitmq:" + input));

消费者 A

//定义队列
channel.QueueDeclare(QUEUENAME, true, false, false);
//定义交换机
channel.ExchangeDeclare(TESTEXCHANGE, ExchangeType.Direct, true, false);
//绑定队列到交换机
channel.QueueBind(QUEUENAME, TESTEXCHANGE, "INFO");

消费者 B

//定义队列
channel.QueueDeclare(QUEUENAME, true, false, false);
//定义交换机
channel.ExchangeDeclare(TESTEXCHANGE, ExchangeType.Direct, true, false);
//绑定队列到交换机
channel.QueueBind(QUEUENAME, TESTEXCHANGE, "ERROR");

绑定成功后,发送消息,消费者A可以收到消息,消费者B无法收到消息。

如果遇到指定routingKey生产一条消息,结果 AB消费者都收到的情况。建议在RabbitMQ后台的交换机下看一下绑定的Queue是否重复绑定了多个routingKey.

如何用.NETCore操作RabbitMQ

topic通配符模式

如何用.NETCore操作RabbitMQ

在通配符模式下,RabbitMQ使用模糊匹配来决定把消息推送给哪个生产者。通配符有两个符号来匹配routingKey

1.*匹配一个字符 如:*.qq.com 可匹配 1.qq.com

2.#匹配一个或者多个字符。 如:*.qq.com 可匹配 1.qq.com或者1111.qq.com

其他的操作基本和routing模式一样。

header模式

header模式是把routingkey放到header中.取消掉了routingKey。并使用一个字典传递 K、V的方式来匹配。
比如同时要给用户发送邮件和短信,可直接通过header的键值对来匹配绑定的值,把消息传递给发短信和邮件的生产者.

以上就是如何用.NETCore操作RabbitMQ的详细内容,更多关于.NETCore 操作RabbitMQ的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/boxrice/p/14475574.html

延伸 · 阅读

精彩推荐
  • C#C#使用Aspose.Cells创建和读取Excel文件

    C#使用Aspose.Cells创建和读取Excel文件

    这篇文章主要为大家详细介绍了C#使用Aspose.Cells创建和读取Excel文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    在代码的世界里游走11012022-03-02
  • C#C#程序异常关闭时的捕获

    C#程序异常关闭时的捕获

    这篇文章主要为大家详细介绍了C# Winform程序异常关闭时,进行捕获并记录日志,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Alan.hsiang7672022-02-27
  • C#c# 通过WinAPI播放PCM声音

    c# 通过WinAPI播放PCM声音

    这篇文章主要介绍了c# 通过WinAPI播放PCM声音的方法,帮助大家更好的理解和使用c#编程语言,感兴趣的朋友可以了解下...

    天方11502022-10-21
  • C#在C#中global关键字的作用及其用法

    在C#中global关键字的作用及其用法

    global 是 C# 2.0 中新增的关键字,理论上说,如果代码写得好的话,根本不需要用到它,但是不排除一些特别的情况,比如修改别人的代码,本文仅举例说明...

    王景3782021-11-17
  • C#解析在C#中接口和类的异同

    解析在C#中接口和类的异同

    今天小编就为大家分享一篇关于解析在C#中接口和类的异同,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来...

    Mogul19532022-03-08
  • C#C#实现猜数字小游戏

    C#实现猜数字小游戏

    这篇文章主要为大家详细介绍了C#实现猜数字小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    fanxingyue9592022-08-29
  • C#C# 如何获取出错的错误所在行数信息

    C# 如何获取出错的错误所在行数信息

    本文主要介绍 C# 中获取错误所在行的方法,在开发过程中或是用户在使用过程中,出错的话方便我们快速定位到错误的位置,以便我们处理。...

    yourber4882021-11-19
  • C#浅谈C#中List<T>对象的深度拷贝问题

    浅谈C#中List<T>对象的深度拷贝问题

    下面小编就为大家带来一篇浅谈C#中List<T>对象的深度拷贝问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    C#教程网11612021-04-28