RabbitMQ交换机(Exchanges)
目录
一、概念
二、临时队列
三、绑定
四、Fanout(扇出交换机)
(一)介绍
(二)实战
五、Direct(直接交换机)
(一)介绍
(二)实战
六、Topic(主题交换机)
(一)介绍
(二)案例
(三)实战
七、Header(头部交换机)
一、概念

交换机的类型:直接(direct), 主题(topic) ,标题(headers) , 扇出(fanout)
无名 exchange
channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes() );
二、临时队列
String queueName = channel.queueDeclare().getQueue(); 
三、绑定

四、Fanout(扇出交换机)
(一)介绍
(二)实战
我们声明一个logs交换机以及创建两个临时队列绑定在交换机上,routeKey为空字符串,当EmitLog生产者向logs交换机发消息时两个队列都接收得到。这个即为扇出交换机。
ReceiveLogs01 将接收到的消息打印在控制台
public class ReceiveLogs01 {private final static String EXCHANGE_NAME = "logs";public static void main(String[] args) throws IOException {Channel channel = RabbitMqUtils.getChannel();/** 生成一个临时的队列,队列名字随机*/String queueName = channel.queueDeclare().getQueue();// 将临时队列绑定在我们定义的交换机上,路由Key为空字符串channel.queueBind(queueName, EXCHANGE_NAME, "");// 接收消息回调函数DeliverCallback deliverCallback = (consumerTag, message) -> {System.out.println("ReceiveLogs01控制台打印接收到的消息:" + new String(message.getBody()));};channel.basicConsume(queueName, true, deliverCallback, (consumerTag -> {}));}
}
ReceiveLogs02 将接收到的消息打印在控制台
public class ReceiveLogs02 {private final static String EXCHANGE_NAME = "logs";public static void main(String[] args) throws IOException {Channel channel = RabbitMqUtils.getChannel();/** 生成一个临时的队列,队列名字随机*/String queueName = channel.queueDeclare().getQueue();// 将临时队列绑定在我们定义的交换机上,路由Key为空字符串channel.queueBind(queueName, EXCHANGE_NAME, "");DeliverCallback deliverCallback = (consumerTag, message) -> {System.out.println("ReceiveLogs02控制台打印接收到的消息:" + new String(message.getBody()));};channel.basicConsume(queueName, true, deliverCallback, (consumerTag -> {}));}
}
EmitLog 发送消息给两个消费者接收
public class EmitLog {private final static String EXCHANGE_NAME = "logs";public static void main(String[] args) throws IOException {// 获取信道Channel channel = RabbitMqUtils.getChannel();// 交换机声明,在生产者声明消费者方就不用声明了channel.exchangeDeclare(EXCHANGE_NAME, "fanout");// 控制台输入内容充当消息发送Scanner scanner = new Scanner(System.in);while(scanner.hasNext()) {String message = scanner.next();channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());System.out.println("生产者发出消息");}}
}
总结:
当交换机内的队列routeKey为空字符串时,此时向该交换机发送消息且routeKey也为空字符串的话那么所有的队列都接收得到消息,即为扇出交换机。
五、Direct(直接交换机)
(一)介绍
当我们想对某一个队列单独发送消息,可以根据设置不同的routeKey来达到这种效果,这就是直接交换机。

多重绑定无非就是绑定的时候多出一条queueBind
channel.queueBind(queue_name, EXCHANGE_NAME, "info");
channel.queueBind(queue_name, EXCHANGE_NAME, "waring");
(二)实战

此时队列的声明需要放在消费者方,因为每个消费者代表不同的队列,对于交换机的声明可以放在生产者
消费者01
public class ReceiveLogsDirect01 {private static final String EXCHANGE_NAME = "direct_logs";public static void main(String[] args) throws IOException {Channel channel = RabbitMqUtils.getChannel();String queue_name = "console";channel.queueDeclare(queue_name, false, false, false, null);channel.queueBind(queue_name, EXCHANGE_NAME, "info");channel.queueBind(queue_name, EXCHANGE_NAME, "waring");DeliverCallback deliverCallback = (consumerTag, message) -> {System.out.println("ReceiveLogsDirect01收到消息" + new String(message.getBody()));};channel.basicConsume(queue_name, deliverCallback, (consumerTag -> {}));}
}
消费者02
public class ReceiveLogsDirect02 {private static final String EXCHANGE_NAME = "direct_logs";public static void main(String[] args) throws IOException {Channel channel = RabbitMqUtils.getChannel();String queue_name = "disk";channel.queueDeclare(queue_name, false, false, false, null);channel.queueBind(queue_name, EXCHANGE_NAME, "error");DeliverCallback deliverCallback = (consumerTag, message) -> {System.out.println("ReceiveLogsDirect02收到消息" + new String(message.getBody()));};channel.basicConsume(queue_name, deliverCallback, (consumerTag -> {}));}
}
生产者
public class EmitLogDirect {private final static String EXCHANGE_NAME = "direct_logs";public static void main(String[] args) throws IOException {Channel channel = RabbitMqUtils.getChannel();/** 生产者并不知道消息会发向哪个队列,他只是指明找哪个交换机中的路由key* 由交换机去寻找队列传递消息*/Scanner sc = new Scanner(System.in);while(sc.hasNext()) {String message = sc.next();channel.basicPublish(EXCHANGE_NAME, "info", null, message.getBytes());}}
}
总结:
我们可以通过指定routeKey来向对应的队列单独发消息,即为直接交换机
六、Topic(主题交换机)
(一)介绍
- *(星号)可以代替一个单词
- #(井号)可以替代零个或多个单词
(二)案例

队列Q1的routeKey为“*.orange.*”,Q2的routeKey有两个,分别为“*.*.rabbit”和“lazy.#”
- 当一个队列绑定键是#,那么这个队列将接收所有数据,就有点像 fanout 了
- 如果队列绑定键当中没有#和*出现,那么该队列绑定类型就是 direct 了
(三)实战
消费者01
public class ReceiveLogsTopic01 {public static final String EXCHANGE_NAME = "topic_logs";public static void main(String[] args) throws IOException {Channel channel = RabbitMqUtils.getChannel();String queueName = "Q1";channel.queueDeclare(queueName, false, false, false, null);channel.queueBind(queueName, EXCHANGE_NAME, "*.orange.*");System.out.println("ReceiveLogsTopic01等待接收消息...");DeliverCallback deliverCallback = (consumeTag, message) -> {System.out.println("接收队列:" + queueName + "绑定键:" + message.getEnvelope().getRoutingKey());System.out.println("接收到消息:" + new String(message.getBody()));};channel.basicConsume(queueName, true, deliverCallback, (consumerTag -> {}));}
}
消费者02
public class ReceiveLogsTopic02 {public static final String EXCHANGE_NAME = "topic_logs";public static void main(String[] args) throws IOException {Channel channel = RabbitMqUtils.getChannel();String queueName = "Q2";channel.queueDeclare(queueName, false, false, false, null);channel.queueBind(queueName, EXCHANGE_NAME, "*.*.rabbit");channel.queueBind(queueName, EXCHANGE_NAME, "lazy.#");System.out.println("ReceiveLogsTopic02等待接收消息...");DeliverCallback deliverCallback = (consumeTag, message) -> {System.out.println("接收队列:" + queueName + "绑定键:" + message.getEnvelope().getRoutingKey());System.out.println("接收到消息:" + new String(message.getBody()));};channel.basicConsume(queueName, true, deliverCallback, (consumerTag -> {}));}
}
生产者
public class EmitLogTopic {public static final String EXCHANGE_NAME = "topic_logs";public static void main(String[] args) throws IOException {Channel channel = RabbitMqUtils.getChannel();channel.exchangeDeclare(EXCHANGE_NAME, "topic");Map<String, String> bindingKeyMap = new HashMap<>();bindingKeyMap.put("quick.orange.rabbit","被队列 Q1Q2 接收到");bindingKeyMap.put("lazy.orange.elephant","被队列 Q1Q2 接收到");bindingKeyMap.put("quick.orange.fox","被队列 Q1 接收到");bindingKeyMap.put("lazy.brown.fox","被队列 Q2 接收到");bindingKeyMap.put("lazy.pink.rabbit","虽然满足两个绑定但只被队列 Q2 接收一次");bindingKeyMap.put("quick.brown.fox","不匹配任何绑定不会被任何队列接收到会被丢弃");bindingKeyMap.put("quick.orange.male.rabbit","是四个单词不匹配任何绑定会被丢弃");bindingKeyMap.put("lazy.orange.male.rabbit","是四个单词但匹配 Q2");for(Map.Entry<String, String> bindingKeyMapEntry : bindingKeyMap.entrySet()) {String bindingKey = bindingKeyMapEntry.getKey();String message = bindingKeyMapEntry.getValue();channel.basicPublish(EXCHANGE_NAME, bindingKey, null, message.getBytes());System.out.println("生产者发出消息:" + message);}}
}
结果

七、Header(头部交换机)
由于header交换机不常用,这里简单介绍

相关文章:
RabbitMQ交换机(Exchanges)
目录 一、概念 二、临时队列 三、绑定 四、Fanout(扇出交换机) (一)介绍 (二)实战 五、Direct(直接交换机) (一)介绍 (二)实…...
2023年java初级面试题10道基础试水题
1、面向对象的特征有哪些方面?答:面向对象的特征主要有以下几个方面:1)抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节…...
烙铁使用方法
烙铁使用 烙铁是硬件工程师最经常使用的工具之一,一把性能保持良好的烙铁能帮助我们快速进行电路调试。烙铁第一次加热时采用焊锡均匀涂覆在烙铁头上,以便去除包在烙铁头上面的氧化物。在工作中我们需要根据情况选择合适的烙铁头类型,合适的温度进行操作。完成焊接后要在烙铁…...
golang日期转换、日期增减计算、时间戳转换
// 固定日期格式format : "2006-01-02 15:04:05"// 按本地时区解析日期location, _ : time.ParseInLocation(format, "2022-02-20 11:30:00", time.Local)// 增加1年,三个参数分别是:年,月,日date : location…...
Android 多种支付方式的优雅实现
场景App 的支付流程,添加多种支付方式,不同的支付方式,对应的操作不一样,有的会跳转到一个新的webview,有的会调用系统浏览器,有的会进去一个新的表单页面,等等。并且可以添加的支付方式也是不确…...
算法设计与分析期末考试复习(三)
动态规划 动态规划算法与分治法类似,其基本思想也是将待求解问题分成若干个子问题。但是经分解得到的子问题往往不是互相独立的。在用分治法求解时,有些子问题被重复计算机了许多次。 如果能够保存已解决的子问题的答案,而在需要时再找出已求…...
ZCMU--1970: 潜伏者
Description R 国和 S 国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动。 历尽艰险后,潜伏于 S 国的 R 国间谍小 C 终于摸清了 S 国军用密码的编码规则: 1. S 国军方内部欲发送的原信息经过加…...
containerd安装配置
containerd基本使用命令 containerd安装 容器运行时containerd安装配置 https://blog.csdn.net/rendongxingzhe/article/details/124595415 yum list | grep containerd containerd的本地CLI工具ctr命令 containerd的组件 containerd提供包括容器的运行、测试、发布和接口…...
随机森林算法(Random Forest)R语言实现
随机森林1. 使用Boston数据集进行随机森林模型构建2. 数据集划分3.构建自变量与因变量之间的公式4. 模型训练5. 寻找合适的ntree6. 查看变量重要性并绘图展示7. 偏依赖图:Partial Dependence Plot(PDP图)8. 训练集预测结果1. 使用Boston数据集进行随机森…...
干货 | 八条“黄金规则”解决RF电路寄生信号
PART 01 接地通孔应位于接地参考层开关处流经所布线路的所有电流都有相等的回流。耦合策略固然很多,不过回流通常流经相邻的接地层或与信号线路并行布置的接地。在参考层继续时,所有耦合都仅限于传输线路,一切都非常正常。不过,如…...
Java虚拟机之类加载学习总结
文章目录1 什么是类加载1.1 类加载的应用1.2 类加载过程1.3 类的验证1.4 类初始化顺序2 类加载时机3 类加载器3.1 类加载分类3.2 双亲委派3.3 自定义类加载器3.4 类加载器的命名空间4 打破双亲委派4.1 线程上下文类加载器4.2 自定义类加载器5 类的卸载1 什么是类加载 Java 虚拟…...
基于 vue3、vite、antdv、css 变量实现在线主题色切换
1、前言动态切换主题是一个很常见的需求. 实现方案也有很多, 如:编译多套 css 文件, 然后切换类名(需要预设主题, 不够灵活)less 在线编译(不兼容 ie, 性能较差)css 变量(不兼容 ie)但是这些基本都是针对 vue2 的, 我在网上并没有找到比较完整的解决 vue3 换肤的方案, 大多只处…...
“笨办法”学Python 3 ——练习 44 继承和组合
练习44 继承和组合 永远记住这一点:继承的大多数用法都可以用组合(composition)来简化或替换。并且无论如何都要避免多重继承。 内容提要: 1. 什么是继承? (1)隐式继承 (2&#x…...
绕过安全狗拦截的SQL注入
目录 靶场环境及中间件 知识补充 判断存在注入 整形get类注入 字符型GET注入...
JAVA练习62-无重复字符的最长子串、最长回文子串
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、题目1-无重复字符的最长子串 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 二、题目2-最长回文子串 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总…...
【JavaWeb】复习重点内容
✅✅作者主页:🔗孙不坚1208的博客 🔥🔥精选专栏:🔗JavaWeb从入门到精通(持续更新中) 📋📋 本文摘要:本篇文章主要分享JavaWeb的学习重点内容。 &a…...
基于粒子群改进的灰色神经网络的时间序列预测,PSO-GNN模型,神经网络案例之20
目标 灰色模型原理 神经网络原理 灰色神经网络原理 粒子群算法的原理 粒子群改进灰色神经网络原理 粒子群改进灰色神经网络的代码实现 效果图 结果分析 展望 灰色模型 基本思想是用原始数据组成原始序列(0),经累加生成法生成序列(1),它可以弱化原始数据的随机性,使其呈现…...
Java中的反射使用
1、获取Class对象的三种方式 1、对象调用Object类的getClass()方法(对象.getClass()) 2、调用类的class属性(类名.class) 3、调用Class类的静态方法(Class.forName(“包名.类名”))常用 Student类 package…...
urho3d工具
AssetImporter 加载开放资源导入库支持的各种三维格式(http://assimp.sourceforge.net/)并保存Urho3D模型、动画、材质和场景文件。有关支持的格式列表,请参阅http://assimp.sourceforge.net/main_features_formats.html. Blender的另一种导出路径是使用Urho3D插件…...
HashMap数据结构
HashMap概述 HashMap是基于哈希表的Map接口实现的,它存储的是内容是键值对<key,value>映射。此类不保证映 射的顺序,假定哈希函数将元素适当的分布在各桶之间,可为基本操作(get和put)提供稳定的性能。 HashMap在JDK1.8以前数据结构和存…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
