常用的消息队列
MSMQ:微软自带的消息队列,使用的人少,不开源
rabbitMQ:开源,支持语言多,使用比较广泛,社区支持强
rocketMQ:阿里巴巴的消息队列,开源,但是商业版是收费的,除了java语言其他语言支持的都不好
消息队列的主要作用
1. 异步调用,延迟处理
2. 应用解耦
3. 处理高并发
abbitMQ 安装
rabbitMQ是使用erlang语言开发的,所以安装rabbitMQ时同时也要安装erlang语言(官网就可以下)
都安装好后在安装文件夹sbin中打开命令窗口
输入一下命令启动rabbitMQ
rabbitmq-plugins enable rabbitmq_management
看到这样就启动成功了
然后需要重启一下rabbitMQ服务
现在rabbitMQ服务就已经成功启动l
rabbitMQ默认地址http://localhost:15672/
默认账号密码 :guest / guest
看到这个页面消息队列就可以使用了
现在通过消息队列来产生一条消息
首先下载这个NuGetbao
创建一个链接的工厂类
ConnectionFactory connectionFactory = new ConnectionFactory() { HostName ="localHost",UserName ="guest",Password = "guest",Port= 5672 };
services.AddSingleton<ConnectionFactory>(connectionFactory);
构造函数注入一下
private readonly ILogger<HomeController> _logger;
//链接工厂类
private readonly ConnectionFactory _connectionFactory;
public HomeController(ILogger<HomeController> logger, IStudent student, IFreeSql FreeSql, ConnectionFactory connectionFactory)
{
_logger = logger;
_connectionFactory = connectionFactory;
}
产生消息(交换机和队列创建一次就好了,后面直接用,不需要重复创建)
//创建消息队列
//创建链接
using ( var conn =_connectionFactory.CreateConnection())
{
//创建通道
using (var channel = conn.CreateModel())
{
//创建一个交换机(交换机的名字,交换机的类型)
channel.ExchangeDeclare("MYExchange", "direct");
//创建一个队列("队列的名字","是否持久化","排外性","是否自动删除","参数")
channel.QueueDeclare("maoyuan",false,false, false,null);
//将交换机与队列进行绑定(不绑定就无法明确消息药推送到那个消息队列)(队列名,交换机名,路由key)路由key自己定义的名字
channel.QueueBind( "maoyuan", "MYExchange","Test key");
//模拟101条消息
for (int i = 1; i <= 101; i++)
{
byte[] mesg = System.Text.Encoding.UTF8.GetBytes("hello RabbitMQ"+i);
//把消息放到消息队列里边去(交换机名字,路由key,属性,真正的消息)(路由Key通过交换机与队列的绑定的来)
channel.BasicPublish("MYExchange", "Test key", null, mesg);
}
}
}
现在来看看产生了多少条消息
顺便再提一下交换机
交换机的几种类型
direct 完全匹配模式
交换机与队列绑定的路由键与把消息放到消息队列里边去的路由键需要完全匹配
topic 模糊匹配
交换机与队列绑定的路由键与把消息放到消息队列里边去的路由键模糊匹配,通过*设置模糊匹配
fanout 广播方式(效率最快,因为不需要处理路由键)
不需要路由键,交换机直接将消息发送到和它关联的队列
headers 设置header去决定路由
现在消息已经产生了,那怎么消费呢
两种方法
1.以事件的方式消费
2.一条一条的消费
先来看看以事件的方式消费
public IActionResult Xiaofei()
{
//创建链接
using (var conn = factory.CreateConnection())
{
//打开一个通道
using (var channel = conn.CreateModel())
{
//绑定一个通道
EventingBasicConsumer eventingBasicConsumer = new EventingBasicConsumer(channel);
eventingBasicConsumer.Received += EventingBasicConsumer_Received;
//使用事件的方式(队列名称,是否立马应答,绑定事件)(如果不想消息被重复读取将 false改为true)
channel.BasicConsume("maoyuan", false, eventingBasicConsumer);
}
}
return View();
}
/// <summary>
/// 消息消费事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void EventingBasicConsumer_Received(object sender, BasicDeliverEventArgs e)
{
var body = e.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
}
现在来看看一行一行的获取消息
List<string> list = new List<string>();
//获取消息总条数
uint messagecount = channel.MessageCount("maoyuan");
BasicGetResult result;
for (int i = 0; i < messagecount; i++)
{
//一行一行的获取(队列名,是否自动删除)
result = channel.BasicGet("maoyuan", false);
list.Add(Encoding.UTF8.GetString(result.Body.ToArray()));
}
消息队列答应模式
自动确认:
获取消息后自动删除,更方便
手动确认:
获取消息后用户自动调用是否确认收到消息,然后在删除消息,可控性更强
记录一下,第一次在CSDN写博客