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; 【出版社…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
文件上传漏洞防御全攻略
要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...