RabbitMQ消息队列(八)-通过Topic主题模式分发消息(.Net Core版)
前两章我们讲了RabbitMQ的direct模式和fanout模式,本章介绍topic主题模式的应用。如果对direct模式下通过routingkey来匹配消息的模式已经有一定了解那fanout也很好理解。简单的可以理解成direct是通过routingkey精准匹配的,而topic是通过routingkey来模糊匹配。
在topic模式下支持两个特殊字符的匹配。
- * (星号) 代表任意 一个单词
- # (井号) 0个或者多个单词
注意:上面说的是单词不是字符。
如下图所示,RabbitMQ direct模式通过RoutingKey来精准匹配,RoutingKey为red的投递到Queue1,RoutingKey为black和white的投递到Queue2。
我们可以假设一个场景,我们要做一个日志模块来收集处理不同的日志,日志区分包含三个维度的标准:模块、日志紧急程度、日志重要程度。模块分为:red、black、white;紧急程度分为:critical、normal;把重要程度分为:medium、low、high在RoutingKey字段中我们把这三个维度通过两个“.“连接起来。
现在我们需要对black模块,紧急程度为critical,重要程度为high的日志分配到队列1打印到屏幕;对所以模块重要程度为high的日志和white紧急程度为critical的日志发送到队列2持久化到硬盘。如下示例:
RoutingKey为“black.critical.high”的日志会投递到queue1和queue2,。
RoutingKey为“red.critical.high”的日志会只投递到queue2。
RoutingKey为“white.critical.high”的日志会投递到queue2,并且虽然queue2的两个匹配规则都符合但只会向queue2投递一份。
新建TopicProduct用来发布三种routingkey的消息。
- using System;
- using System.Text;
- using RabbitMQ.Client;
- using RabbitMQ.Client.Events;
- namespace TopicProduct
- {
- class Program
- {
- static void Main(string[] args)
- {
- String exchangeName = "wytExchangeTopic";
- String routeKeyName1 = "black.critical.high";
- String routeKeyName2 = "red.critical.high";
- String routeKeyName3 = "white.critical.high";
- String message1 = "black-critical-high!";
- String message2 = "red-critical-high!";
- String message3 = "white-critical-high!";
- ConnectionFactory factory = new ConnectionFactory();
- factory.HostName = "192.168.63.129";
- factory.Port = ;
- factory.VirtualHost = "/wyt";
- factory.UserName = "wyt";
- factory.Password = "wyt";
- using (IConnection connection=factory.CreateConnection())
- {
- using (IModel channel=connection.CreateModel())
- {
- channel.ExchangeDeclare(exchange: exchangeName, type: "topic", durable: true, autoDelete: false, arguments: null);
- IBasicProperties properties = channel.CreateBasicProperties();
- properties.Persistent = true;
- Byte[] body1 = Encoding.UTF8.GetBytes(message1);
- Byte[] body2 = Encoding.UTF8.GetBytes(message2);
- Byte[] body3 = Encoding.UTF8.GetBytes(message3);
- //消息推送
- channel.BasicPublish(exchange: exchangeName, routingKey:routeKeyName1,basicProperties: properties, body: body1);
- channel.BasicPublish(exchange: exchangeName, routingKey: routeKeyName2, basicProperties: properties, body: body2);
- channel.BasicPublish(exchange: exchangeName, routingKey: routeKeyName3, basicProperties: properties, body: body3);
- Console.WriteLine(" [x] Sent {0}", message1);
- Console.WriteLine(" [x] Sent {0}", message2);
- Console.WriteLine(" [x] Sent {0}", message3);
- }
- }
- Console.WriteLine(" Press [enter] to exit.");
- Console.ReadLine();
- }
- }
- }
新建TopicCustomerA接收一种消息
- using System;
- using System.Text;
- using RabbitMQ.Client;
- using RabbitMQ.Client.Events;
- namespace TopicCustomerA
- {
- class Program
- {
- static void Main(string[] args)
- {
- String exchangeName = "wytExchangeTopic";
- String routeKeyName1 = "black.critical.high";
- ConnectionFactory factory = new ConnectionFactory();
- factory.HostName = "192.168.63.129";
- factory.Port = ;
- factory.VirtualHost = "/wyt";
- factory.UserName = "wyt";
- factory.Password = "wyt";
- using (IConnection connection=factory.CreateConnection())
- {
- using (IModel channel=connection.CreateModel())
- {
- channel.ExchangeDeclare(exchange: exchangeName, type: "topic", durable: true, autoDelete: false, arguments: null);
- String queueName = channel.QueueDeclare().QueueName;
- channel.QueueBind(queue: queueName, exchange: exchangeName, routingKey: routeKeyName1, arguments: null);
- EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
- consumer.Received += (model, ea) =>
- {
- var body = ea.Body;
- var message = Encoding.UTF8.GetString(body);
- var routingKey = ea.RoutingKey;
- Console.WriteLine(" [x] Received '{0}':'{1}'", routingKey, message);
- channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
- };
- channel.BasicConsume(queue: queueName, autoAck: false, consumer: consumer);
- Console.WriteLine(" Press [enter] to exit.");
- Console.ReadLine();
- }
- }
- }
- }
- }
新建TopicCustomerB接收两种消息
- using System;
- using System.Text;
- using RabbitMQ.Client;
- using RabbitMQ.Client.Events;
- namespace TopicCustomerB
- {
- class Program
- {
- static void Main(string[] args)
- {
- String exchangeName = "wytExchangeTopic";
- String routeKeyName1 = "red.critical.*";
- String routeKeyName2 = "white.critical.*";
- ConnectionFactory factory = new ConnectionFactory();
- factory.HostName = "192.168.63.129";
- factory.Port = ;
- factory.VirtualHost = "/wyt";
- factory.UserName = "wyt";
- factory.Password = "wyt";
- using (IConnection connection = factory.CreateConnection())
- {
- using (IModel channel = connection.CreateModel())
- {
- channel.ExchangeDeclare(exchange: exchangeName, type: "topic", durable: true, autoDelete: false, arguments: null);
- String queueName = channel.QueueDeclare().QueueName;
- channel.QueueBind(queue: queueName, exchange: exchangeName, routingKey: routeKeyName1, arguments: null);
- channel.QueueBind(queue: queueName, exchange: exchangeName, routingKey: routeKeyName2, arguments: null);
- EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
- consumer.Received += (model, ea) =>
- {
- var body = ea.Body;
- var message = Encoding.UTF8.GetString(body);
- var routingKey = ea.RoutingKey;
- Console.WriteLine(" [x] Received '{0}':'{1}'", routingKey, message);
- channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
- };
- channel.BasicConsume(queue: queueName, autoAck: false, consumer: consumer);
- Console.WriteLine(" Press [enter] to exit.");
- Console.ReadLine();
- }
- }
- }
- }
- }
先运行TopicCustomerA和TopicCustomerB保持订阅状态。然后执行TopicProduct发布消息。TopicCustomerA和TopicCustomerB收到的消息如下:
如上截图,验证了我们之前的结论。
另外还有一些特殊情况例如:
- 如果binding_key 是 “#” - 它会接收所有的Message,不管routing_key是什么,就像是fanout
- exchange。
- 如果 “*” and “#” 没有被使用,那么topic exchange就变成了direct exchange。
RabbitMQ消息队列(八)-通过Topic主题模式分发消息(.Net Core版)的更多相关文章
- (八)RabbitMQ消息队列-通过Topic主题模式分发消息
原文:(八)RabbitMQ消息队列-通过Topic主题模式分发消息 前两章我们讲了RabbitMQ的direct模式和fanout模式,本章介绍topic主题模式的应用.如果对direct模式下通过 ...
- Spring Boot 之 RabbitMQ 消息队列中间件的三种模式
开门见山(文末附有消息队列的几个基本概念) 1.直接模式( Direct)模式 直白的说就是一对一,生产者对应唯一的消费者(当然同一个消费者可以开启多个服务). 虽然使用了自带的交换器(Exchang ...
- (九)RabbitMQ消息队列-通过Headers模式分发消息
原文:(九)RabbitMQ消息队列-通过Headers模式分发消息 Headers类型的exchange使用的比较少,以至于官方文档貌似都没提到,它是忽略routingKey的一种路由方式.是使用H ...
- RabbitMQ入门教程(十七):消息队列的应用场景和常见的消息队列之间的比较
原文:RabbitMQ入门教程(十七):消息队列的应用场景和常见的消息队列之间的比较 分享一个朋友的人工智能教程.比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看. 这是网上的一篇教程写的很好,不知原作 ...
- (转)RabbitMQ消息队列(九):Publisher的消息确认机制
在前面的文章中提到了queue和consumer之间的消息确认机制:通过设置ack.那么Publisher能不到知道他post的Message有没有到达queue,甚至更近一步,是否被某个Consum ...
- RabbitMQ消息队列(九):Publisher的消息确认机制
在前面的文章中提到了queue和consumer之间的消息确认机制:通过设置ack.那么Publisher能不到知道他post的Message有没有到达queue,甚至更近一步,是否被某个Consum ...
- (五)RabbitMQ消息队列-安装amqp扩展并订阅/发布Demo(PHP版)
原文:(五)RabbitMQ消息队列-安装amqp扩展并订阅/发布Demo(PHP版) 本文将介绍在PHP中如何使用RabbitMQ来实现消息的订阅和发布.我使用的系统依然是Centos7,为了方便, ...
- RabbitMQ消息队列(七)-通过fanout模式将消息推送到多个Queue中(.Net Core版)
前面第六章我们使用的是direct直连模式来进行消息投递和分发.本章将介绍如何使用fanout模式将消息推送到多个队列. 有时我们会遇到这样的情况,多个功能模块都希望得到完整的消息数据.例如一个log ...
- Rabbitmq消息队列(六) 主题交换机
1.简介 前面学习了有选择性的接收消息,但是却没有办法基于多个标准来接收消息.为了实现这个目的,接下来我们学习如何使用另一种更复杂的交换机 —— 主题交换机. 2.主题交换机 发送到主题交换机(top ...
随机推荐
- 我的 FPGA 学习历程(08)—— 实验:点亮单个数码管
数码管是一种常见的用于显示的电子器件,根据数码管大致可以分为共阴极和共阳极两种,下图所示的是一个共阳极的数码管的电路图(摘自金沙滩工作室的 51 开发板电路图),我的 AX301 开发板与这张图的情况 ...
- Egret的容器--删除对象,遮罩
class P91F extends egret.Sprite { public constructor() { super(); this.addEventListener(egret.Event. ...
- centos docker 升级至最新稳定版--摘自官网
亲测好使 删除老版本的docker sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ do ...
- vue组件之间的传值方式
一.父组件向子组件传值方式 1.1父组件向子组件传数据方式 <!DOCTYPE html> <html lang="en"> <head> &l ...
- Redis配置参数详解
Redis配置参数详解 /********************************* GENERAL *********************************/ // 是否作为守护进 ...
- 了解vue APi
阳光那么好,何必自寻烦恼,过好每一个当下,一万个美丽的未来抵不过一个温暖的现在. 一.Vue.nextTick(): 该api 是在Dom节点更新结束之后执行的一个延时回调.在修改数据之后,立即使用这 ...
- 判断js中的数据类型的几种方法
判断js中的数据类型有一下几种方法:typeof.instanceof. constructor. prototype. $.type()/jquery.type(),接下来主要比较一下这几种方法的异 ...
- html+css手机端自动适应
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scal ...
- mysql5.7忽略大小写问题
mysql5.7忽略大小写问题 1.1 前言 新安装mysql5.7版本后,linux环境下默认是大小写敏感的. 1.2 忽略大小写敏感步骤 进入mysql配置文件: vi /et ...
- 格式化数据保留两位小数,输入格式为 :xxx,xx,,,,x,,(x为浮点数)
/** * 格式化字符串 */ static String dataFormat(String data){ String formatedData = ""; // 浮点数正则表 ...