springboot与rabbitmq的整合【演示5种基本交换机】
前言:
👏作者简介:我是笑霸final,一名热爱技术的在校学生。
📝个人主页:个人主页1 || 笑霸final的主页2
📕系列专栏:后端专栏
📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀
🔥如果感觉博主的文章还不错的话,👍点赞👍 + 👀关注👀 + 🤏收藏🤏
话不多说 直接开干
目录
- 一 导入maven坐标与配置
- 二、直连交换机direct exchange
- 2.1配置类QueueConfig
- 2.2消息提供者
- 2.2消息消费者
- 2.3测试类
- 三、默认交换机default exchange
- 3.1配置类和消息提供者
- 3.2消息消费者
- 3.3测试结果
- 四、扇型交换机fanout exchange
- 4.1配置类
- 4.2消息提供者
- 4.3消息消费者
- 4.4测试类
- 五、主题交换机topic exchanges
- 5.1配置类
- 5.2消息提供者
- 5.3消息消费者
- 5.4测试
- 六、头交换机 headers exchange
- 6.1配置类
- 6.2创建消息提供者
- 6.3消息消费者
- 6、4测试结果
一 导入maven坐标与配置
<!--rabbitmq--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>
基础配置文件
spring:rabbitmq:username: 你的用户名password: 你的密码host: rabbitmq安装的主机的 ip地址port: 5672 #端口号
二、直连交换机direct exchange
直连型交换机(direct exchange)是根据消息携带的路由键(routing key)将消息投递给对应队列的。
- 将一个队列 绑定到 某个交换机上,同时赋予该绑定一个路由键(routing key)
- 当一个携带着路由键为
routingKey01的消息被发送给直连交换机时,交换机会把它路由给绑定值同样为routingKey01的队列。
直连交换机经常用来循环分发任务给多个工作者(workers)。当这样做的时候,我们需要明白一点,在AMQP 0-9-1中,消息的负载均衡是发生在消费者(consumer)之间的,而不是队列(queue)之间。

2.1配置类QueueConfig
@Configuration
public class QueueConfig {/*** 创建一个队列 队列名为direct1* */@Beanpublic Queue queue01(){return new Queue("direct1",true);//true表示持久化}/*** 创建一个直连交换机 名为directExchange* */@Beanpublic DirectExchange directExchange(){return new DirectExchange("directExchange");}/*** 在让队列和直连交换机绑定在一起* */@Beanpublic Binding binding(){Binding binding= BindingBuilder.bind(queue01()).to(directExchange()).with("routingKey01");return binding;}}
2.2消息提供者
@Component
public class MqProducer {@Resourceprivate RabbitTemplate rabbitTemplate;public void sent_test(Object o){//convertAndSend(交换机的名字,交换机中路由键名称,参数)rabbitTemplate.convertAndSend("directExchange",//交换机名字"routingKey01",//路由keyo);}
}
2.2消息消费者
@Component
@Slf4j
public class MqConsumer {/*** 接收消息*/@RabbitListener(queues = {"direct1"})public void receivedD(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("当前时间:{},消费者1收到消息:{}",new Date().toString(),msg);}}
我写了两个消费者内容一致
2.3测试类
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SpringRunnerTest {@Resourceprivate MqProducer mqProducer;//注入消息提供者@Testpublic void test_send() throws InterruptedException {// 循环发送消息while (true) {mqProducer.sent_test("你好,我是Lottery 001");Thread.sleep(3500);}}
}
测试结果

三、默认交换机default exchange
默认交换机(default exchange)实际上是一个由消息代理预先声明好的没有名字(名字为空字符串)的直连交换机(direct exchange)。它有一个特殊的属性使得它对于简单应用特别有用处:那就是每个新建队列(queue)都会自动绑定到默认交换机上,绑定的路由键(routing key)名称与队列名称相同。
3.1配置类和消息提供者
/**
*配置类
*/
@Configuration
public class QueueConfig {
//只需要创建一个队列
//每个`新建队列`(queue)都会`自动`绑定到`默认交换机`上,
//绑定的`路由键(routing //key)名称`与`队列名称` 相同@Beanpublic Queue queue02(){return new Queue("def");}}
/**
*消息提供者
*/
@Component
public class MqProducer {@Resourceprivate RabbitTemplate rabbitTemplate;public void def_sent_test(Object obj){//convertAndSend(交换机的名字,交换机中路由键名称,参数)rabbitTemplate.convertAndSend(//没有名字(名字为空字符串)"","def",obj);//消息内容}
}
默认交换机名字是
空字符串。每个新建队列(queue)都会自动绑定到默认交换机上,绑定的路由键(routing key)名称与队列名称相同。
3.2消息消费者
@Component
@Slf4j
public class MqConsumer {/*** 接收消息*/@RabbitListener(queues = {"def"})public void receivedD02(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("当前时间:{},消费者收到消息:{}",new Date().toString(),msg);}}
3.3测试结果
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SpringRunnerTest {@Resourceprivate MqProducer mqProducer;//注入消息提供者@Testpublic void test_send02() throws InterruptedException {// 循环发送消息while (true) {mqProducer.def_sent_test("测试默认交换机");Thread.sleep(3500);}}
}

四、扇型交换机fanout exchange
扇型交换机(fanout exchange)将消息路由给绑定到它身上的所有队列,而不理会绑定的路由键。如果N个队列绑定到某个扇型交换机上,当有消息发送给此扇型交换机时,交换机会将消息的拷贝分别发送给这所有的N个队列。扇型用来交换机处理消息的广播路由(broadcast routing)
这个交换机上的路由键将失效
4.1配置类
@Configuration
public class QueueConfig {/*** 创建多个队列* @return*/@Beanpublic Queue queue03_1(){return new Queue("fanout03_1");}@Beanpublic Queue queue03_2(){return new Queue("fanout03_2");}@Beanpublic Queue queue03_3(){return new Queue("fanout03_3");}/*** 创建一个扇形交换机*/@Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange("fanoutExchange");}/*** 队列和扇形交换机绑定*/@Beanpublic Binding binding_3_1(){Binding binding= BindingBuilder.bind(queue03_1()).to(fanoutExchange());return binding;}@Beanpublic Binding binding_3_2(){Binding binding= BindingBuilder.bind(queue03_2()).to(fanoutExchange());return binding;}@Beanpublic Binding binding_3_3(){Binding binding= BindingBuilder.bind(queue03_3()).to(fanoutExchange());return binding;}
}
4.2消息提供者
@Component
public class MqProducer {@Resourceprivate RabbitTemplate rabbitTemplate;/*** 扇形交换机*/public void fanout_sent_test(Object o){//convertAndSend(交换机的名字,交换机中路由键名称,参数)rabbitTemplate.convertAndSend("fanoutExchange","",//扇形交换机也没有路由建o);}}
注意:扇形交换机也
没有路由key也用空字符串
4.3消息消费者
@Component
@Slf4j
public class MqConsumer {@RabbitListener(queues = {"fanout03_1"})public void receivedD03_1(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("绑定队列一 当前时间:{},消费者收到消息:{}",new Date().toString(),msg);}@RabbitListener(queues = {"fanout03_2"})public void receivedD03_2(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("绑定队列二 当前时间:{},消费者收到消息:{}",new Date().toString(),msg);}@RabbitListener(queues = {"fanout03_3"})public void receivedD03_3(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("绑定队列三 当前时间:{},消费者收到消息:{}",new Date().toString(),msg);}
}
4.4测试类
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SpringRunnerTest {@Resourceprivate MqProducer mqProducer;//注入消息提供者@Testpublic void test_send03() throws InterruptedException {int a=1;// 循环发送消息while (true) {mqProducer.fanout_sent_test("测试扇形交换机 第"+ a++ +"次循环");Thread.sleep(3500);}}
}

五、主题交换机topic exchanges
主题交换机(topic exchanges)通过对消息的
路由键和队列到交换机的绑定模式之间的匹配,将消息路由给一个或多个队列。主题交换机经常用来实现各种分发/订阅模式及其变种。主题交换机通常用来实现消息的多播路由(multicast routing)。

5.1配置类
@Configuration
public class QueueConfig {/*** 创建;两个队列*/@Beanpublic Queue topicQueue_1(){return new Queue("topicQueue_1");}@Beanpublic Queue topicQueue_2(){return new Queue("topicQueue_2");}/*** 创建主题交换机*/@Beanpublic TopicExchange TopicExchange(){return new TopicExchange("TopicExchange");}/*** 根据不同的key绑定不同的队列*/@Beanpublic Binding bindingTopicExchange_1(){Binding binding= BindingBuilder.bind(topicQueue_1()).to(TopicExchange()).with("key1");return binding;}@Beanpublic Binding bindingTopicExchange_2(){Binding binding= BindingBuilder.bind(topicQueue_2()).to(TopicExchange()).with("key2");return binding;}
}
5.2消息提供者
@Component
public class MqProducer {@Resourceprivate RabbitTemplate rabbitTemplate;/*** 主题交换机*/public void topic_sent_test(Object o,String key){rabbitTemplate.convertAndSend("TopicExchange",key, //后面动态的传递keyo);}
}
5.3消息消费者
@Component
@Slf4j
public class MqConsumer1 {/*** 接收消息*/@RabbitListener(queues = {"topicQueue_1"})public void topicQueue_1(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("队列一 当前时间:{},消费者收到消息:{}",new Date().toString(),msg);}@RabbitListener(queues = {"topicQueue_2"})public void topicQueue_2(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("队列二 当前时间:{},消费者收到消息:{}",new Date().toString(),msg);}}
5.4测试
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SpringRunnerTest {@Resourceprivate MqProducer mqProducer;//注入消息提供者@Testpublic void test_send04() throws InterruptedException {// 循环发送消息int a=1;while (true) {if(a%2 == 0){mqProducer.topic_sent_test("!!给队列二的消息==第"+ a++ +"次循环","key2");}else{mqProducer.topic_sent_test("!!给队列一的消息==第"+ a++ +"次循环","key1");}Thread.sleep(3500);}}
}

使用案例:
- 分发有关于特定地理位置的数据,例如销售点
- 由多个工作者(workers)完成的后台任务,每个工作者负责处理某些特定的任务
- 股票价格更新(以及其他类型的金融数据更新)
- 涉及到分类或者标签的新闻更新(例如,针对特定的运动项目或者队伍)
- 云端的不同种类服务的协调
- 分布式架构/基于系统的软件封装,其中每个构建者仅能处理一个特定的架构或者系统。
六、头交换机 headers exchange
有时消息的路由操作会涉及到多个属性,此时使用消息头就比用路由键更容易表达,头交换机(headers exchange)就是为此而生的。头交换机使用多个
消息属性来代替路由键建立路由规则。通过判断消息头的值能否与指定的绑定相匹配来确立路由规则。
6.1配置类
@Configuration
public class QueueConfig {/*** 创建2个队列*/@Bean(name = "headersQ1")public Queue queue1() {return new Queue("headersQ1");}@Bean(name = "headersQ2")public Queue queue2() {return new Queue("headersQ2");}/*** 创建交换机* @return*/@Beanpublic HeadersExchange headersExchange() {return new HeadersExchange("headersExchange");}/*** 绑定交换机和队列*/@Beanpublic Binding binding1() {HashMap<String, Object> header = new HashMap<>();header.put("queue", "queue1");header.put("bindType", "whereAll");return BindingBuilder.bind(queue1()).to(headersExchange()).whereAll(header).match();}@Beanpublic Binding binding2() {HashMap<String, Object> header = new HashMap<>();header.put("queue", "queue2");header.put("bindType", "whereAny");return BindingBuilder.bind(queue2()).to(headersExchange()).whereAny(header).match();}
}
6.2创建消息提供者
@Component
public class MqProducer {@Resourceprivate RabbitTemplate rabbitTemplate;/*** 头交换机* @param msg*/public void headers_send(String msg,int a) {//a用来控制头信息 达到传递给不同的队列效果MessageProperties messageProperties = new MessageProperties();if( a % 3 ==0){messageProperties.setHeader("queue", "queue2");messageProperties.setHeader("bindType", "whereAny");}else{messageProperties.setHeader("queue", "queue1");messageProperties.setHeader("bindType", "whereAll");}Message message = new Message(msg.getBytes(), messageProperties);rabbitTemplate.convertAndSend("headersExchange", null, message);}
}
6.3消息消费者
@Component
@Slf4j
public class MqConsumer1 {/*** 接收消息*/@RabbitListener(queues = "headersQ1")public void receive1(String msg) {log.info("接收到 headersQ1 发送的消息:" + msg);}@RabbitListener(queues = "headersQ2")public void receive2(String msg) {log.info("接收到 headersQ2 发送的消息:" + msg);}}
6、4测试结果
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SpringRunnerTest {@Resourceprivate MqProducer mqProducer;//注入消息提供者@Testpublic void test_headers_send() throws InterruptedException {// 循环发送消息int a=1;while (true) {mqProducer.headers_send("消息"+a,a++);Thread.sleep(3500);}}
}

相关文章:
springboot与rabbitmq的整合【演示5种基本交换机】
前言: 👏作者简介:我是笑霸final,一名热爱技术的在校学生。 📝个人主页:个人主页1 || 笑霸final的主页2 📕系列专栏:后端专栏 📧如果文章知识点有错误的地方,…...
【设计模式】设计原则-单一职责原则
单一职责原则 类的设计原则之单一职责原则,是最常用的类的设计的原则之一。 百度百科:就一个类而言,应该仅有一个引起它变化的原因。应该只有一个职责。 通俗的讲就是:一个类只做一件事 这个解释更通俗易懂,也更符…...
【C++】-多态的底层原理
💖作者:小树苗渴望变成参天大树🎈 🎉作者宣言:认真写好每一篇博客💤 🎊作者gitee:gitee✨ 💞作者专栏:C语言,数据结构初阶,Linux,C 动态规划算法🎄 如 果 你 …...
【部署】让你的电脑多出一个磁盘来用!使用SSHFS将远程服务器目录挂载到Windows本地,挂载并共享服务器资源
让你的电脑多出一个磁盘来用!---使用SSHFS将远程服务器目录挂载到Windows本地 1. 方法原理介绍2.SSHFS-Win使用教程—实现远程服务器磁盘挂载本地 由于日常主要用 Windows 系统,每次都得 ssh 到服务器上进行取资源(本地磁盘不富裕)…...
/var/lock/subsys目录的作用
总的来说,系统关闭的过程(发出关闭信号,调用服务自身的进程)中会检查/var/lock/subsys下的文件,逐一关闭每个服务,如果某一运行的服务在/var/lock/subsys下没有相应的选项。在系统关闭的时候,会…...
DETR (DEtection TRansformer)基于自建数据集开发构建目标检测模型超详细教程
目标检测系列的算法模型可以说是五花八门,不同的系列有不同的理论依据,DETR的亮点在于它是完全端到端的第一个目标检测模型,DETR(Detection Transformer)是一种基于Transformer的目标检测模型,由Facebook A…...
C++初阶 - 5.C/C++内存管理
目录 1.C/C的内存分布 2.C语言中动态内存管理方式:malloc、calloc、realloc、free 3.C内存管理方式 3.1 new/delete操作内置类型 3.2 new 和 delete操作自定义类型 4.operator new 与 operator delete 函数(重要点) 4.1 operator new 与…...
数学建模学习(3):综合评价类问题整体解析及分析步骤
一、评价类算法的简介 对物体进行评价,用具体的分值评价它们的优劣 选这两人其中之一当男朋友,你会选谁? 不同维度的权重会产生不同的结果 所以找到每个维度的权重是最核心的问题 0.25 二、评价前的数据处理 供应商ID 可靠性 指标2 指…...
【后端面经】微服务构架 (1-5) | 限流:濒临奔溃?限流守护者拯救系统于水火之中!
文章目录 一、前置知识1、什么是限流?2、限流算法A) 静态算法a) 漏桶b) 令牌桶c) 固定窗口d) 滑动窗口B) 动态算法3、限流的模式4、 限流对象4、限流后应该怎么做?二、面试环节1、面试准备2、基本思路3、亮点展现A) 突发流量(针对请求个数而言)B) 请求大小(针对请求大小而言)…...
HDFS异构存储详解
异构存储 HDFS异构存储类型什么是异构存储异构存储类型如何让HDFS知道集群中的数据存储目录是那种类型存储介质 块存储选择策略选择策略说明选择策略的命令 案例:冷热温数据异构存储对应步骤 HDFS内存存储策略支持-- LAZY PERSIST介绍执行使用 HDFS异构存储类型 冷…...
《面试1v1》Kafka消息是采用Pull还是Push模式
🍅 作者简介:王哥,CSDN2022博客总榜Top100🏆、博客专家💪 🍅 技术交流:定期更新Java硬核干货,不定期送书活动 🍅 王哥多年工作总结:Java学习路线总结…...
Windows环境Docker安装
目录 安装Docker Desktop的步骤 Docker Desktop 更新WSL WSL 的手动安装步骤 Windows PowerShell 拉取(Pull)镜像 查看已下载的镜像 输出"Hello Docker!" Docker Desktop是Docker官方提供的用于Windows的图形化桌面应用程序,…...
Spring 6.0官方文档示例(23): singleton类型的bean和prototype类型的bean协同工作的方法(二)
使用lookup-method: 一、实体类: package cn.edu.tju.domain2;import java.time.LocalDateTime; import java.util.Map;public class Command {private Map<String, Object> state;public Map<String, Object> getState() {return state;}public void …...
Docker Compose 容器编排
Docker compose Docker compose 实现单机容器集群编排管理(使用一个模板文件定义多个应用容器的启动参数和依赖关系,并使用docker compose来根据这个模板文件的配置来启动容器) 通俗来说就是把之前的多条docker run启动容器命令 转换为docker…...
while循环
while循环是一种常见的循环结构,它会重复执行一段代码,直到指定的条件不再满足。 基本语法如下: while 条件: # 循环体代码 其中,条件是一个布尔表达式,如果为True,则执行循环体中的代码;如果…...
从JVM指令看String对象的比较
在翻看各类 java 知识中,总会提到如下知识:比较 String 对象,例如: String a1new String("10"); String a2"10"; String a3"1""0";//结果 System.out.println(a1a2); //false System.ou…...
python与深度学习(六):CNN和手写数字识别二
目录 1. 说明2. 手写数字识别的CNN模型测试2.1 导入相关库2.2 加载数据和模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章训练的模型进行测试…...
Linux使用教程
一、Linux命令基础 1、ls、ll命令——展示数据 ①ls命令——平铺展示数据 其中ls命令以平铺的方式展现数据 ②ll命令——列表展示数据 ll命令以列表的方式展现数据 -a选项,表示:all的意思,即列出全部文件(包含隐藏的文件/文件夹…...
项目名称:智能家居边缘网关项目
一,项目介绍 软件环境: C语言 硬件环境: STM32G030C8TX单片机开发板 开发工具: Linux平台GCC交叉编译环境以及ukeil (1)边缘网关概念 边缘网关是部署在网络边缘侧的网关,通过网络联接、协议转换等功能联接物理和数字世界,提供轻量化的联接管…...
SciencePub学术 | 物联网类重点SCIEEI征稿中
SciencePub学术 刊源推荐: 物联网类重点SCIE&EI征稿中!信息如下,录满为止: 一、期刊概况: 物联网类重点SCIE&EI 【期刊简介】IF:7.5-8.0,JCR1区,中科院1/2区TOP; 【出版社…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果,且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例
目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码:冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...
用 FFmpeg 实现 RTMP 推流直播
RTMP(Real-Time Messaging Protocol) 是直播行业中常用的传输协议。 一般来说,直播服务商会给你: ✅ 一个 RTMP 推流地址(你推视频上去) ✅ 一个 HLS 或 FLV 拉流地址(观众观看用)…...


