消息队列--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进行简单的使用分析,欢迎各位大佬指点批评~

 

posted @ 2018-10-04 09:51  深海里的一条鱼  阅读(364)  评论(0编辑  收藏  举报