NetCore RabbitMQ ,Routing定向模式 RabbitMQ的六種工作模式 NetCore RabbitMQ 發佈訂閱模式,消息廣播

十年河東,十年河西,莫欺少年窮

學無止境,精益求精

上篇博客介紹了RabbitMQ的六種工作模式 RabbitMQ的六種工作模式 

RabbitMQ的簡單模式和Work工作模式請參考:NetCore RabbitMQ 簡介及兔子生產者、消費者 【簡單模式,work工作模式,競爭消費】

RabbitMQ發佈訂閱模式之消息廣播請參考:NetCore RabbitMQ 發佈訂閱模式,消息廣播

本篇博客使用NetCore完成RabbitMQ發佈訂閱模式中的定向模式

何爲定向模式?

1.4 routing路由模式

在這裏插入圖片描述

  1. 消息生產者將消息發送給交換機按照路由判斷,路由是字符串(info) 當前產生的消息攜帶路由字符(對象的方法),交換機根據路由的key,只能匹配上路由key對應的消息隊列,對應的消費者才能消費消息;
  2. 根據業務功能定義路由字符串
  3. 從系統的代碼邏輯中獲取對應的功能字符串,將消息任務扔到對應的隊列中業務場景:error 通知;EXCEPTION;錯誤通知的功能;傳統意義的錯誤通知;客戶通知;利用key路由,可以將程序中的錯誤封裝成消息傳入到消息隊列中,開發者可以自定義消費者,實時接收錯誤;

上圖中X代表交換機,RabbitMQ中交換機的類型分爲四種,分別爲廣播模式,定向模式,通配符模式,參數匹配模式

ExchangeType.Fanout【廣播模式】 

ExchangeType.Direct【定向模式】 

ExchangeType.Topic【通配符模式】 

ExchangeType.Headers 【參數匹配模式】

廣播模式中,我們通過設定相同的RoutingKey,完成消息的廣播,定向模式中,我們只需在隊列綁定交換機時賦值不同的RoutingKey且生產者生產消息時指定響應的RoutingKey即可完成消息定向到對應隊列。

定向模式生產者

定向模式創建生產者,分爲如下步驟,

1、聲明一個交換機

2、聲明廣播的隊列

3、交換機和隊列進行綁定【創建不同的routingKey,用於區分綁定規則】

4、生產消息,生產消息時,指定生產消息的routingKey,已達到消息定向的作用

以上步驟用NetCore 實現如下: 

using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace RabbitMqProducer
{
    class Program
    {
        /// <summary>
        /// 本示例紅色預警爲最高預警級別,藍色預警次之,黃色預警等級最差
        /// 紅色預警隊列中只展示紅色預警消息,
        /// 藍色預警隊列中展示紅色預警和藍色預警 
        /// 黃色預警隊列展示紅、藍、黃三種預警
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "127.0.0.1"; //主機名
            factory.UserName = "guest";//使用的用戶
            factory.Password = "guest";//用戶密碼
            factory.Port = 5672;//端口號
            factory.VirtualHost = "/"; //虛擬主機
            factory.MaxMessageSize = 1024; //消息最大字節數
            using (var connection = factory.CreateConnection()) 
            {
                //rabbitMQ 基於信道進行通信,因此,我們需要實例化信道Channel
                using (var channel = connection.CreateModel())
                {
                    //exchange 交換機名稱
                    //type  交換機類型  ExchangeType.Direct【定向模式】  ExchangeType.Fanout【廣播模式】  ExchangeType.Topic【通配符模式】  ExchangeType.Headers 【參數匹配模式】
                    //durable 是否持久化
                    //autoDelete 隊列是否爲臨時隊列
                    //arguments  其他配置 詳見博客:https://www.cnblogs.com/chenwolong/p/RabbitMQ_S.html
                    //void ExchangeDeclare(string exchange, string type, bool durable, bool autoDelete, IDictionary<string, object> arguments);
                    //聲明一個交換機  類型 : Direct
                    string Ename = "ExRabbitMQ_Direct";
                    channel.ExchangeDeclare(Ename, ExchangeType.Direct, false, false, null);
                    //聲明廣播的隊列
                    string Qname_Red = "RabbitMQ_Queue_Red";
                    string Qname_Blue = "RabbitMQ_Queue_Blue";
                    string Qname_Yellow = "RabbitMQ_Queue_Yellow";
                    channel.QueueDeclare(Qname_Red, false, false, false, null);
                    channel.QueueDeclare(Qname_Blue, false, false, false, null);
                    channel.QueueDeclare(Qname_Yellow, false, false, false, null);
                    //交換機 隊列 綁定
                    //queue 隊列名稱
                    //exchange  交換機名稱
                    //routingKey  路由規則  
                    //void QueueBind(string queue, string exchange, string routingKey, IDictionary<string, object> arguments);
                    string routingKey_Red = "Red"; // 紅色預警
                    string routingKey_Blue = "Blue"; // 藍色預警
                    string routingKey_Yellow = "Yellow"; // 黃色預警
                    //只接受紅色預警
                    channel.QueueBind(Qname_Red, Ename, routingKey_Red);
                    // Qname_Blue接受兩種消息類型
                    channel.QueueBind(Qname_Blue, Ename, routingKey_Red);
                    channel.QueueBind(Qname_Blue, Ename, routingKey_Blue);
                    // Qname_Yellow 介紹三種消息類型
                    channel.QueueBind(Qname_Yellow, Ename, routingKey_Red);
                    channel.QueueBind(Qname_Yellow, Ename, routingKey_Blue);
                    channel.QueueBind(Qname_Yellow, Ename, routingKey_Yellow);
                    //發送消息
                    for(int i = 0; i < 10 ; i++)
                    {
                        var messages_Red = "I am Red Police"; //傳遞的消息內容
                        var messages_Blue = "I am Blue Police"; //傳遞的消息內容
                        var messages_Yellow = "I am Yellow Police"; //傳遞的消息內容
                                                                    //exchange 交換機,如果使用默認的交換機,那麼routingKey要和隊列的名稱一致
                                                                    //routingKey:路由  
                                                                    //basicProperties : 用於基礎屬性設置
                        ///BasicPublish(this IModel model, string exchange, string routingKey, IBasicProperties basicProperties, ReadOnlyMemory<byte> body);
                        channel.BasicPublish(Ename, routingKey_Red, null, Encoding.UTF8.GetBytes(messages_Red + "_" + i)); //生產紅色預警消息
                        channel.BasicPublish(Ename, routingKey_Blue, null, Encoding.UTF8.GetBytes(messages_Blue + "_" + i)); //生產藍色預警消息
                        channel.BasicPublish(Ename, routingKey_Yellow, null, Encoding.UTF8.GetBytes(messages_Yellow + "_" + i)); //生產黃色預警消息
                    }
                }
            }
            Console.Read();
        }
    }
}
View Code

執行上述代碼,得到如下信息

此時:三個隊列中紅色預警隊列有10條消息,藍色預警隊列有20條消息,黃色預警隊列有30條消息

 

 交換機信息,注意交換機的類型爲定向模式

定向模式消費者

【紅色預警隊列消費者】

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace RabbitMqConsumer
{
    class Program
    {
        static void Main(string[] args)
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "127.0.0.1"; //主機名
            factory.UserName = "guest";//使用的用戶
            factory.Password = "guest";//用戶密碼
            factory.Port = 5672;//端口號
            factory.VirtualHost = "/"; //虛擬主機
            factory.MaxMessageSize = 1024; //消息最大字節數
                                           //創建連接
            var connection = factory.CreateConnection();
            //創建通道
            var channel = connection.CreateModel();

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

            //接收到消息事件
            consumer.Received += (ch, ea) =>
            {
                var message = Encoding.UTF8.GetString(ea.Body.ToArray());
                Console.WriteLine($"紅色預警隊列消費者收到紅色預警消息: {message}");
                //確認該消息已被消費
                channel.BasicAck(ea.DeliveryTag, false); Thread.Sleep(100);
            };
            //啓動消費者 
            string Qname = "RabbitMQ_Queue_Red";
            channel.BasicConsume(Qname, false, consumer);
            Console.WriteLine("消費者已啓動");
            Console.ReadKey();
            channel.Dispose();
            connection.Close();
        } 
    }
}
View Code

因爲紅色預警隊列只綁定了紅色預警的RoutingKey,因此,該隊列只接受紅色預警消息

 

 【藍色預警隊列消費者】

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace RabbitMqConsumer
{
    class Program
    {
        static void Main(string[] args)
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "127.0.0.1"; //主機名
            factory.UserName = "guest";//使用的用戶
            factory.Password = "guest";//用戶密碼
            factory.Port = 5672;//端口號
            factory.VirtualHost = "/"; //虛擬主機
            factory.MaxMessageSize = 1024; //消息最大字節數
                                           //創建連接
            var connection = factory.CreateConnection();
            //創建通道
            var channel = connection.CreateModel();

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

            //接收到消息事件
            consumer.Received += (ch, ea) =>
            {
                var message = Encoding.UTF8.GetString(ea.Body.ToArray());
                Console.WriteLine($"藍色預警隊列消費者收到消息: {message}");
                //確認該消息已被消費
                channel.BasicAck(ea.DeliveryTag, false); Thread.Sleep(100);
            };
            //啓動消費者 
            string Qname = "RabbitMQ_Queue_Blue";
            channel.BasicConsume(Qname, false, consumer);
            Console.WriteLine("消費者已啓動");
            Console.ReadKey();
            channel.Dispose();
            connection.Close();
        } 
    }
}
View Code

【黃色預警消費者】

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace RabbitMqConsumer
{
    class Program
    {
        static void Main(string[] args)
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = "127.0.0.1"; //主機名
            factory.UserName = "guest";//使用的用戶
            factory.Password = "guest";//用戶密碼
            factory.Port = 5672;//端口號
            factory.VirtualHost = "/"; //虛擬主機
            factory.MaxMessageSize = 1024; //消息最大字節數
                                           //創建連接
            var connection = factory.CreateConnection();
            //創建通道
            var channel = connection.CreateModel();

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

            //接收到消息事件
            consumer.Received += (ch, ea) =>
            {
                var message = Encoding.UTF8.GetString(ea.Body.ToArray());
                Console.WriteLine($"黃色預警隊列消費者收到消息: {message}");
                //確認該消息已被消費
                channel.BasicAck(ea.DeliveryTag, false); Thread.Sleep(100);
            };
            //啓動消費者 
            string Qname = "RabbitMQ_Queue_Yellow";
            channel.BasicConsume(Qname, false, consumer);
            Console.WriteLine("消費者已啓動");
            Console.ReadKey();
            channel.Dispose();
            connection.Close();
        } 
    }
}
View Code

 

 定向模式中的核心爲路由Key的聲明、路由Key的綁定、發送帶有路由Key的消息,這3點爲實現定向發送的核心。

@陳大六的博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章