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主题模式如下图,生产者创建消息到消息中间件,消费者会接受到订阅的主题中所有的消息.在主题模式下 ...
随机推荐
- Java学习:线程池
线程池 线程池概念:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多的资源. 线程池:容器-->集合(ArrayList,Hash ...
- APUE之第5章——标准I/O库
一.知识回顾:文件I/O 文件 I/O 是不带缓冲的 I/O(unbuffered I/O),指每个 read 和 write 都调用内核中的一个系统调用. 对于内核而言,所有打开的文件都通过文件描述 ...
- Java Mockito 笔记
Mockito 1 Overview 2 Maven 项目初始化 3 示例 3.1 第一个示例 3.2 自动 Mock 3.3 Mock 返回值 3.4 Mock 参数 3.5 自动注入 Mock 对 ...
- WCF学习笔记(一)---我的第一个WCF程序
一.创建WCF程序 1.创建一个控制台程序(WCFBlog) 2.添加wcf项目 3.将默认的IService1和Service1改成自己的名字 4.在ICalculateServic ...
- 《C++ Primer》学习总结;兼论如何使用'书'这种帮助性资料
6.25~ 6.27,用了3天翻了一遍<C++ Primer>. ▶书的 固有坏处 一句话: 代码比 文字描述 好看多了.————> 直接看习题部分/ 看demo就行了 看文字在描述 ...
- 在HTML网页中嵌入脚本的方式
在HTML标记的事件属性中直接添加脚本 <!doctype html> <html> <head> <meta charset="utf-8&quo ...
- Java基础篇(中)
4.Java 关键字 下面列出了 Java 关键字.这些保留字不能用于常量.变量.和任何标识符的名称. 类别 关键字 说明 访问控制 private 私有的 protected 受保护的 public ...
- maven项目整合SSM配置log4j, 实现控制台打印SQL语句
在原有项目正常启动的情况下, 实现在控制台打印mapper包下SQL语句. 1.在pom.xml配置文件中添加两个依赖(缺一不可) <!--日志包--> <dependency> ...
- Django的安全攻击
目录 Django的安全攻击 XSS XSS(跨站脚本攻击) 危害 原理 防护 csrf(Cross Site Request Forgery) csrf(跨站域请求伪造) 过程 Django 提供的 ...
- English--虚拟语气和条件状语从句
English|虚拟语气和条件状语从句 虚拟语气在英语中,还是有一定地位的,毕竟大家都做着我有一百万的梦~~~ 前言 目前所有的文章思想格式都是:知识+情感. 知识:对于所有的知识点的描述.力求不含任 ...