RabbitMQ六种队列模式-主题模式
前言
RabbitMQ六种队列模式-简单队列
RabbitMQ六种队列模式-工作队列
RabbitMQ六种队列模式-发布订阅
RabbitMQ六种队列模式-路由模式
RabbitMQ六种队列模式-主题模式 [本文]
从前面的几篇我们依次经历了 exchange 模式从 fanout > direct 的转变过程,在 fanout 时,我们只能进行简单的广播,对应类型比较单一,使用 direct 后,消费者则可以进行一定程度的选择,但是,direct 还是有局限性,路由不支持多个条件。
怎么讲呢?
direct 不支持匹配 routingKey,一但绑定了就是绑定了,而 topic 主题模式支持规则匹配,只要符合 routingKey 就能发送到绑定的队列上。
文章目录
1. 什么是主题模式2. 代码部分2.1 生产者2.2 *消费者2.3 #消费者2.4 运行截图3. 总结
1. 什么是主题模式
官方链接:http://www.rabbitmq.com/tutorials/tutorial-five-java.html
topics 主题模式跟 routing 路由模式类似,只不过路由模式是指定固定的路由键 routingKey,而主题模式是可以模糊匹配路由键 routingKey,类似于SQL中 = 和 like 的关系。
P 表示为生产者、 X 表示交换机、C1C2 表示为消费者,红色表示队列。
topics 模式与 routing 模式比较相近,topics 模式不能具有任意的 routingKey,必须由
一个英文句点号“.”分隔的字符串(我们将被句点号“.”分隔开的每一段独立的字符串称为一个单词),比如 "lazy.orange.fox"。topics routingKey 中可以存在两种特殊字符“”与“#”,用于做模糊匹配,其中“”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)。
"*" 表示任何一个词
"#" 表示0或1个词
以上图中的配置为例:
如果一个消息的 routingKey 设置为 “xxx.orange.rabbit”,那么该消息会同时路由到 Q1 与 Q2,routingKey="lazy.orange.fox”的消息会路由到Q1与Q2;
routingKey="lazy.brown.fox”的消息会路由到 Q2;
routingKey="lazy.pink.rabbit”的消息会路由到 Q2(只会投递给Q2一次,虽然这个routingKey 与 Q2 的两个 bindingKey 都匹配);
routingKey="quick.brown.fox”、routingKey="orange”、routingKey="quick.orange.male.rabbit”的消息将会被丢弃,因为它们没有匹配任何bindingKey。
接下来代码为例:
2. 代码部分
2.1 生产者
public class ProducerTopic {
private static final String EXCHANGE_NAME = "my_topic_exchange";
public static void main(String[] args) throws IOException, TimeoutException {
/** 1.创建新的连接 */
Connection connection = MQConnectionUtils.newConnection();
/** 2.创建通道 */
Channel channel = connection.createChannel();
/** 3.绑定的交换机 参数1交互机名称 参数2 exchange类型 */
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
/** 4.发送消息 */
String routingKey = "log.info.error";
String msg = "topic_exchange_msg:" + routingKey;
System.out.println("[send] = " + msg);
channel.basicPublish(EXCHANGE_NAME, routingKey, null, msg.getBytes());
/** 5.关闭通道、连接 */
channel.close();
connection.close();
/** 注意:如果消费没有绑定交换机和队列,则消息会丢失 */
}
}
2.2 *消费者
public class ConsumerLogXTopic {
private static final String QUEUE_NAME = "topic_consumer_info";
private static final String EXCHANGE_NAME = "my_topic_exchange";
public static void main(String[] args) throws IOException, TimeoutException {
System.out.println("log * 消费者启动");
/* 1.创建新的连接 */
Connection connection = MQConnectionUtils.newConnection();
/* 2.创建通道 */
Channel channel = connection.createChannel();
/* 3.消费者关联队列 */
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
/* 4.消费者绑定交换机 参数1 队列 参数2交换机 参数3 routingKey */
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "log.*");
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
throws IOException {
String msg = new String(body, "UTF-8");
System.out.println("消费者获取生产者消息:" + msg);
}
};
/* 5.消费者监听队列消息 */
channel.basicConsume(QUEUE_NAME, true, consumer);
}
}
2.3 #消费者
public class ConsumerLogJTopic {
private static final String QUEUE_NAME = "topic_consumer_info";
private static final String EXCHANGE_NAME = "my_topic_exchange";
public static void main(String[] args) throws IOException, TimeoutException {
System.out.println("log # 消费者启动");
/* 1.创建新的连接 */
Connection connection = MQConnectionUtils.newConnection();
/* 2.创建通道 */
Channel channel = connection.createChannel();
/* 3.消费者关联队列 */
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
/* 4.消费者绑定交换机 参数1 队列 参数2交换机 参数3 routingKey */
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "log.#");
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
throws IOException {
String msg = new String(body, "UTF-8");
System.out.println("消费者获取生产者消息:" + msg);
}
};
/* 5.消费者监听队列消息 */
channel.basicConsume(QUEUE_NAME, true, consumer);
}
}
2.4 运行截图
生产者
星花*消费者
#消费者
3. 总结
1、topic 相对于之前几种算是比较复杂了,简单来说,就是每个队列都有其关心的主题,所有的消息都带有一个“标题”(RouteKey),exchange 会将消息转发到所有关注主题能与 routeKey 模糊匹配的队列。
2、在进行绑定时,要提供一个该队列关心的主题,如“#.sscai.#”表示该队列关心所有涉及 sscai 的消息(一个 routeKey 为 "club.sscai.tmax”的消息会被转发到该队列)。
3、"#”表示0个或若干个关键字,“”表示一个关键字。如“club.”能与“club.sscai”匹配,无法与“club.sscai.xxx”匹配;但是“club.#”能与上述两者匹配。
4、同样,如果 exchange 没有发现能够与 routeKey 匹配的 Queue,则会抛弃此消息。
案例代码:https://www.lanzous.com/i5ydu6d
我创建了一个java相关的公众号,用来记录自己的学习之路,感兴趣的小伙伴可以关注一下微信公众号哈:niceyoo
RabbitMQ六种队列模式-主题模式的更多相关文章
- RabbitMQ六种队列模式-简单队列模式
前言 RabbitMQ六种队列模式-简单队列 [本文]RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...
- RabbitMQ六种队列模式-工作队列模式
前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列 [本文]RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...
- RabbitMQ六种队列模式-发布订阅模式
前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅 [本文]RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...
- RabbitMQ六种队列模式-路由模式
前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式 [本文]RabbitMQ六种队列模式-主 ...
- 队列模式&主题模式
# RabbitMQ 消息中间件 **Advanced Message Queuing Protocol (高级消息队列协议** The Advanced Message Queuing Protoc ...
- (九)RabbitMQ消息队列-通过Headers模式分发消息
原文:(九)RabbitMQ消息队列-通过Headers模式分发消息 Headers类型的exchange使用的比较少,以至于官方文档貌似都没提到,它是忽略routingKey的一种路由方式.是使用H ...
- (七)RabbitMQ消息队列-通过fanout模式将消息推送到多个Queue中
原文:(七)RabbitMQ消息队列-通过fanout模式将消息推送到多个Queue中 前面第六章我们使用的是direct直连模式来进行消息投递和分发.本章将介绍如何使用fanout模式将消息推送到多 ...
- ActiveMQ--模式(队列模式/主题模式)
两种模式:队列模式/主题模式 pom.xml <dependency> <groupId>org.apache.activemq</groupId> <art ...
- ActiveMQ队列、主题模式区别
1.ActiveMQ队列模式如下图,生产者创建消息到消息中间件,再“均分给消费者”. 2.ActiveMQ主题模式如下图,生产者创建消息到消息中间件,消费者会接受到订阅的主题中所有的消息.在主题模式下 ...
随机推荐
- js 加密方法Encrypt
function Encrypt(str, pwd) { if (str == "") return ""; str = escape(str); if (!p ...
- javascript异步编程学习及实例
所谓异步就是指给定了一串函数调用a,b,c,d,各个函数的执行完结返回过程并不顺序为a->b->c->d(这属于传统的同步编程模式),a,b,c,d调用返回的时机并不确定. 对于js ...
- Python网络编程、爬虫之requests模块使用
一.python操作网络,也就是打开一个网站,或者请求一个http接口,使用urllib模块. urllib模块是一个标准模块,直接import urllib即可,在python3里面只有urllib ...
- Test Title
test testing... testing in day02... testing in day07...
- 2019 京东java面试笔试总结 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.京东等公司offer,岗位是Java后端开发,因为发展原因最终选择去了京东,入职一年时间了,也成为了面试官, ...
- 使用Python搭建http服务器
David Wheeler有一句名言:“计算机科学中的任何问题,都可以通过加上另一层间接的中间层解决.”为了提高Python网络服务的可移植性,Python社区在PEP 333中提出了Web服务器网关 ...
- layui 表格中实现照片预览,点击查看原图
人员表格中实现照片预览,并且可点击放大.查看原图 <table id="dutyInfoTable" class="layui-hide">< ...
- Android源码分析(三)-----系统框架设计思想
一 : 术在内而道在外 Android系统的精髓在源码之外,而不在源码之内,代码只是一种实现人类思想的工具,仅此而已...... 近来发现很多关于Android文章都是以源码的方向入手分析Androi ...
- 你与BAT只差这一套面试题
1.Linux如何挂载windows下的共享目录?mount.cifs //IP地址/server /mnt/server -o user=administrator,password=123456l ...
- 关于升级.NetCore3.1启动运行项目之后无法运行之前版本的错误解决方案
昨天在跟上微软的进度,更新VS版本升级.netcore3.1 之后成功运行之后发现,我无法运行之前版本的问题 都是报这种问题: 还有打开解决方案所有的项目都无法正常加载,都是"已卸载&quo ...