消息队列--RabbitMQ(二)
1.常用的几种队列简介
RabbitMQ有五种常用的队列,分别是:简单队列、work模式、发布订阅模式、路由模式、主题(Topic)模式。其实发布订阅、路由、主题这三种模式都从属于与routingkey相关的模式,所以从性质上来说可以说是属于同一类。接下来,我们就以简述与代码的形式,来分别解释一下这几种模式。
2.相关名词解释
Publish:发布者(消息的生产方)
Consumer:使用者(消息的消耗方)
Exchange:交换机(消息的中转站)--后面与routingkey相关的模式会做出相应的解释
VirtrulHost:虚拟主机(在消息系统内开辟的一个放置或者是寄存队列的一个区域,相当于数据库概念)
Queue:消息队列(相当于数据库中的表)
Channel:通道(构建消费者与生产者消息沟通的渠道)
3.几种队列模式的简述及编码实现
(1)简单模式:
所谓简单模式就是由一个生产者、一个消费者,外加一个渠道构建的最为简单的生产消费模式。生产者通过渠道完成消息的推送,消费者接受消息并使用,如此简单。
eg. Client
//1.构建一个连接工厂
var factory = new ConnectionFactory() {
HostName="localhost",//主机名
Port=5672, //端口号
VirtualHost="/lsh-blog", //要使用的虚拟主机名
UserName="lsh", //账号
Password="lsh" //密码
};
Console.WriteLine("接下来要发10条消息。。。");
//2.构建一个连接
using (var connection = factory.CreateConnection())
{
//3。构建一个通道
using (var channel = connection.CreateModel())
{
channel.QueueDeclare("lko",false,false,false,null);
//推送消息
string msg = "我来发布一条最简单的消息";
//推送消息
channel.BasicPublish("",routingKey: "",
basicProperties: null,
body: Encoding.UTF8.GetBytes(msg));
}
}
Console.ReadKey();
Consumer:
/*
consumer
*/
Console.WriteLine("接收消息中。。。");
var factory = new ConnectionFactory()
{
HostName = "localhost",
Port = 5672,
VirtualHost = "/lsh-blog",
UserName = "lsh",
Password = "lsh",
};
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(queue: "lko",
durable: false,
exclusive: false,
autoDelete: true,
arguments: null);
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [Consumer] Received {0}", message);
Thread.Sleep(2000);
channel.BasicAck(ea.DeliveryTag, false);
};
channel.BasicConsume(queue: "lko",
noAck: false,
consumer: consumer);
Console.ReadLine();
(2)Work模式
由一个生产者、多个消费者以及驱动组成。RabbitMQ队列有一个消息竞争原则,就是同时消费同一条队列的几个消费者,对于队列的消息都是谁先获取就被谁消费,没有重复或者不被消费这一说。因而,该模式只是一种特性,所以就不用代码说明啦。
(3) 发布订阅模式
发布订阅就是生产方发布一个入口,使用方就可以接入这个入口,从而做到数据的流通。这样的话,所有的使用方都可以接入这个入口,从而得到数据信息。该模式所需要借助的,便是交换机(Exchange)这个概念,以交换机作为入口,消费使用者进行绑定接入。
eg. Publish
//1.构建一个连接工厂
var factory = new ConnectionFactory() {
HostName="localhost",//主机名
Port=5672, //端口号
VirtualHost="/lsh-blog", //要使用的虚拟主机名
UserName="lsh", //账号
Password="lsh" //密码
};
Console.WriteLine("接下来要发10条消息。。。");
//2.构建一个连接
using (var connection = factory.CreateConnection())
{
//3。构建一个通道
using (var channel = connection.CreateModel())
{
//定义交换机(fanout为交换机类型)
channel.ExchangeDeclare("search_direct", "fanout");
//推送消息
string msg = "我来发布一条最简单的消息";
//推送消息
channel.BasicPublish("search_direct", routingKey: "",
basicProperties: null,
body: Encoding.UTF8.GetBytes(msg));
}
}
Console.ReadKey();
Consumer:
/*
consumer
*/
Console.WriteLine("接收消息中。。。");
var factory = new ConnectionFactory()
{
HostName = "localhost",
Port = 5672,
VirtualHost = "/lsh-blog",
UserName = "lsh",
Password = "lsh",
};
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(queue: "lko",
durable: false,
exclusive: false,
autoDelete: true,
arguments: null);
//将队列lko与交换机search_direct进行绑定接入
channel.QueueBind("lko", "search_direct","");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [Consumer] Received {0}", message);
Thread.Sleep(2000);
channel.BasicAck(ea.DeliveryTag, false);
};
channel.BasicConsume(queue: "lko",
noAck: false,
consumer: consumer);
Console.ReadLine();
(4) 路由模式
路由模式就是以交换机为开发接口,rotingkey作为唯一的过滤筛选标识来实现消息 的发布与使用。这样的话,消费者就可以只消费绑定当前交换机发过来的某一个或某一些rotingkey的消息进行选择性处理啦。发布方,我们只需在上面说过的发布订阅模式的交换及类型fanout改为direct(即:channel.ExchangeDeclare("search_direct", "fanout"), channel.BasicPublish("search_direct", routingKey: "",basicProperties: null,body: Encoding.UTF8.GetBytes(msg));),消费使用方绑定自己队列想要接收的某一些routngkey的消息即可(即: channel.QueueBind("lko", "search_direct","item.del");channel.QueueBind("lko", "search_direct","item.add");…).
(5)Topic话题模式
可以说是带有模糊匹配消费性质的路由模式,也就是说,发布方的交换机类型变成topic,其余的可以保持原封不变,而接收方可以消费一个消费区间或者也可以说是符合某条件的routingkey集合的进行消费使用(即:消费方channel.QueueBind("lko", "search_direct","item.#"),来匹配所有以item开头的所有roukingkey的消息进行消费使用)
4.总结
至此,RabbitMQ常用的几种消费队列模式就简单的介绍完啦,可能有不是很完善的介绍说明,还请诸位多多谅解,后期会不断的完善。下一篇,我将谈一下我所了解的RabbitMQ的使用场景及基于C#的RabbitMQ.dll客户端相关封装的一款组件—EasyNetMQ进行简单的使用分析,欢迎各位大佬指点批评~