十年河東,十年河西,莫欺少年窮
學無止境,精益求精
上一節介紹了RabbitMQ定向模式,本篇介紹 Topics 通配符模式
我的系列博客:
NetCore RabbitMQ 簡介及兔子生產者、消費者 【簡單模式,work工作模式,競爭消費】
kafka、Rabbitmq、EasyNetQ NetCore 源碼下載
本篇介紹Topics通配符模式
1.5 topic 主題模式(路由模式的一種)
- 星號井號代表通配符
- 星號1個字符井號代表0個或多個字符
- 路由功能添加模糊匹配
- 消息產生者產生消息,把消息交給交換機
- 交換機根據key的規則模糊匹配到對應的隊列,由隊列的監聽消費者接收消息消費
Topics通配符模式和定向模式類似,都是通過RoutingKey定向到不到的隊列中,不同的是Topics通配符模式只是通配符,有了通配符,就可以做到模糊匹配。
Topics模式中支持兩種通配符
* 代表1個字符
# 代表0個或多個字符
例如
路由Key定義爲 *.Dog.* ,那麼我們發送消息時中間爲Dog且前後均爲一個字符的路由key都可以匹配到該通配符,例如:C.Dog.D 【注意要帶上 . 】
路由Key定義爲 #.Dog ,那麼發送消息時以Dog結尾的路由Key都可以匹配到該通配符,例如 chenwolong.Dog【注意要帶上 . 】
路由Key定義爲 Dog.# ,那麼發送消息時以Dog開頭的路由Key都可以匹配到該通配符 ,例如 Dog.Chenwolong【注意要帶上 . 】
路由Key定義爲 #.# ,那麼 Dog.Cat,Cat.Dog . 等都可以匹配
下面由代碼進行說明
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_Topic"; channel.ExchangeDeclare(Ename, ExchangeType.Topic, false, false, null); //聲明廣播的隊列 string Qname_Red = "Queue_Red"; string Qname_Blue = "Queue_Blue"; channel.QueueDeclare(Qname_Red, false, false, false, null); channel.QueueDeclare(Qname_Blue, 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"; // 藍色預警 // channel.QueueBind(Qname_Red, Ename, routingKey_Red); // channel.QueueBind(Qname_Blue, Ename, routingKey_Blue); //發送消息 for(int i = 0; i < 10 ; i++) { var messages_HotRed = "#號匹配0個或多個字符,我是高溫紅色預警(Red.Hot)"; //傳遞的消息內容 var messages_FloodRed = "#號匹配0個或多個字符,我是洪澇紅色預警(Red.Floot)"; //傳遞的消息內容 var messages_Blue = "*號匹配一個字符,我是藍色預警(A.Blue)"; //傳遞的消息內容 //exchange 交換機,如果使用默認的交換機,那麼routingKey要和隊列的名稱一致 //routingKey:路由 //basicProperties : 用於基礎屬性設置 ///BasicPublish(this IModel model, string exchange, string routingKey, IBasicProperties basicProperties, ReadOnlyMemory<byte> body); //注意發送消息時,路由Key的匹配規則 channel.BasicPublish(Ename, "Red.Hot", null, Encoding.UTF8.GetBytes(messages_HotRed + "_" + i)); //生產高溫紅色預警消息 channel.BasicPublish(Ename, "Red.Flood", null, Encoding.UTF8.GetBytes(messages_FloodRed + "_" + i)); //生產洪澇紅色預警消息 channel.BasicPublish(Ename, "A.Blue", null, Encoding.UTF8.GetBytes(messages_Blue + "_" + i)); //生產藍色預警消息 } } } Console.Read(); } } }
藍色預警消費者端如下:
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 = "Queue_Blue"; channel.BasicConsume(Qname, false, consumer); Console.WriteLine("消費者已啓動"); Console.ReadKey(); channel.Dispose(); connection.Close(); } } }
紅色預警消費者端如下:
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 = "Queue_Red"; channel.BasicConsume(Qname, false, consumer); Console.WriteLine("消費者已啓動"); Console.ReadKey(); channel.Dispose(); connection.Close(); } } }
上一節定向模式中,需要多次綁定,本節通配符模式可以模糊匹配
@天才臥龍的博客