SpringBoot整合RabbitMQ学习笔记

SpringBoot整合RabbitMQ学习笔记

以下三种类型的消息,生产者和消费者需各自启动一个服务,模拟生产者服务发送消息,消费者服务监听消息,分布式开发。

一 Fanout类型信息

在这里插入图片描述
在这里插入图片描述

  1. . RabbitMQ创建交换机和队列
    在RabbitMQ控制台,新建交换机hmall.fanout,新建两个队列,fanout.queue1和fanout.queue2,并将连个队列和交换机进行绑定即可。
    操作如下图所示:
    一下操作可以通过代码实现,具体参考配置类
    (1)创建队列
    在这里插入图片描述

(2)创建交换机
在这里插入图片描述
(3)绑定
在这里插入图片描述2. 代码实现
(1)引入依赖

<dependency><groupId>org.springframework.book</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

(2)配置MQ配置信息

spring:rabbitmq:host: 192.168.150.101 #主机ipport: 5672 #端口virtual-host: /hmall #虚拟主机username: hmall #用户名password: 123 #密码exchange: hmall.fanoutproducer:queue1: fanout.queue1

(3)声明队列和交换机配置类

@Component
public class FanoutConfg{@Value("${spring.rabbitmq.exchange}")private String exchange@Value("${spring.rabbitmq.producer.queue1}")private String queueName1// 声明fanout交换机@Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange(exchanage);}// 声明队列@Beanpublic Queue fanoutQueue1(){return new Queue(queueName1);}//绑定队列和交换机@Beanpublic Binding bindingQueue1(Queue fanoutQueue1,FanoutExchange fanoutExchange){return BindingBuilder,build(fanoutQueue1).to(fanoutExchange);}
}

(4)生产者

@Component
public class RabbitMqProduce {@Autowiredprivate RabbitTemplate rabbitTemplete;@value("${spring.rabbitmq.producer.queue})private String queueName;/*** 入参说明:* 第一个参数:queueName:队列名称* 第二个参数:路由键,fanout类型不需要路由键* 第三个参数:msg 消息题内容*/public void send(String msg){rabbitTemplete.covertAndSend(queueName,null,msg);}}

(4)消费者

@Component
public class RabbitMqListener {@RabbitListener(queues="${spring.rabbitmq.producer.queue}")public void counsume(String msg){System.out.pringln("消费者收到 fanout.queue队列发的消息",msg);}
}

(5)测试类

@SpringBootTest
public class SpringBootTest{@AUtowiredprivate RabbitMqProduce producer;@Testpublic void testSendFanoutMsg(){producer.send("fanout类型发送消息!!!");}
}

二 direct类型发送消息在这里插入图片描述

在这里插入图片描述

  1. 控制台操作
    (1)交换机和队列的创建参考fanout的操作
    (2)绑定:与fanout不同的是 给交换机绑定队列的同时需要指定路由键,如下图所示:
    在这里插入图片描述
  2. 代码实现
    (1)依赖引入参考fanout类型的消息
    (2)mq消息配置
spring:rabbitmq:host: 192.168.150.101 #主机ipport: 5672 #端口virtual-host: /hmall #虚拟主机username: hmall #用户名password: 123 #密码exchange: hmall.directproducer:queue1: direct.queue1queue2: direct.queue2routingKey1: redroutingKey2: red2

(3)MQ配置类
以下配置可以在消费者注解上实现

@Component
public class RabbitMqConfig {@Autowiredprivate RabbitTemplate rabbitTemplete;@value("${spring.rabbitmq.producer.exchange}")private String exchange;@value("${spring.rabbitmq.producer.queue1}")private String queueName1;@value("${spring.rabbitmq.producer.queue2}")private String queueName2;@value("${spring.rabbitmq.producer.routingKey1}")private String routingKey1;@value("${spring.rabbitmq.producer.routingKey2}")private String routingKey2;// 创建交换机@Bean("directExchange")public Exchange getExchange(){return ExchangeBuilder.topicExchange(exchange) // 交换机类型,交换机名称.durable(true) //ture为持久化,存到磁盘,false存到内存.build();}// 创建队列@Bean("directQueue1")public Queue getDirectQueue1(){retuen new Queue(queueName1);}// 交换机绑定队列@beanpublic Binging bindDirectQueue1(@Qualifier("directExchange") Exchange exchange,@Qualifier("directQueue1") Queue queue){return BindingBuilder.bind(queue).to(exchange).with(routingKey1).noargs();	}// 创建队列@Bean("directQueue2")public Queue getDirectQueue2(){retuen new Queue(queueName2);}// 交换机绑定队列@beanpublic Binging bindDirectQueue2(@Qualifier("directExchange") Exchange exchange,@Qualifier("directQueue2") Queue queue){return BindingBuilder.bind(queue).to(exchange).with(routingKey2).noargs();	}}

(4)生产者发送消息

@Component
public class RabbitMqProduce {@Autowiredprivate RabbitTemplate rabbitTemplete;@value("${spring.rabbitmq.producer.queue1})private String queueName1;@value("${spring.rabbitmq.producer.queue2})private String queueName2;@value("${spring.rabbitmq.producer.routingKey2})private String routingKey1;@value("${spring.rabbitmq.producer.routingKey1})private String routingKey2;/*** 入参说明:* 第一个参数:queueName:队列名称* 第二个参数:路由键,fanout类型不需要路由键* 第三个参数:msg 消息题内容*/public void sendQueue1(String msg){rabbitTemplete.covertAndSend(queueName1,routingKey1,msg);}public void sendQueue2(String msg){rabbitTemplete.covertAndSend(queueName2,routingKey2,msg);}}

(5)消费者监听消息
第一种:已经编写了配置类

@Component
public class RabbitMqListener {@RabbitListener(queues="${spring.rabbitmq.producer.queue1}")public void counsume(String msg){System.out.pringln("消费者收到 direct.queue1队列发的消息",msg);}@RabbitListener(queues="${spring.rabbitmq.producer.queue2}")public void counsume(String msg){System.out.pringln("消费者收到 direct.queue2队列发的消息",msg);}
}

第二种:在注解上配置交换机和队列以及路由键

@Component
public class RabbitMqListener {@RabbitListener(bindings = @QueueBinding(value = Queue(name="${spring.rabbitmq.producer.queue1}",durable="true"),exchange = @Exchange(name="${spring.rabbitmq.producer.exchange)",type=ExchangeType.DIRECT),key = {"${spring.rabbitmq.producer.routingKey1}","${spring.rabbitmq.producer.routingKey2}"}	))public void counsume(String msg){System.out.pringln("消费者收到 direct.queue1队列发的消息",msg);}@RabbitListener(bindings = @QueueBinding(value = Queue(name="${spring.rabbitmq.producer.queue2}",durable="true"),exchange = @Exchange(name="${spring.rabbitmq.producer.exchange)",type=ExchangeType.DIRECT),key = {"${spring.rabbitmq.producer.routingKey1}","${spring.rabbitmq.producer.routingKey2}"}	))public void counsume(String msg){System.out.pringln("消费者收到 direct.queue2队列发的消息",msg);}
}

(6)测试类

@SpringBootTest
public class SpringBootTest{@AUtowiredprivate RabbitMqProduce producer;@Testpublic void testSendDirectMsg(){producer.send("direct类型发送消息!!!");}
}

三 Topic类型消息

在这里插入图片描述
在这里插入图片描述

  1. 控制台操作
    参考前面的创建交换机,队列,以及绑定关系操作
  2. 代码实现
    (1)依赖引入参考fanout类型的消息
    (2)mq消息配置
    路由键使用通配符进行匹配,#代表多个,*代表一个
spring:rabbitmq:host: 192.168.150.101 #主机ipport: 5672 #端口virtual-host: /hmall #虚拟主机username: hmall #用户名password: 123 #密码exchange: hmall.topicproducer:queue1: topic.queue1queue2: topic.queue2routingKey1: china.#routingKey2: #.news

(3)MQ配置类

@Component
public class RabbitMqConfig {@Autowiredprivate RabbitTemplate rabbitTemplete;@value("${spring.rabbitmq.producer.exchange}")private String exchange;@value("${spring.rabbitmq.producer.queue1}")private String queueName1;@value("${spring.rabbitmq.producer.queue2}")private String queueName2;@value("${spring.rabbitmq.producer.routingKey1}")private String routingKey1;@value("${spring.rabbitmq.producer.routingKey2}")private String routingKey2;// 创建交换机@Bean("topicExchange")public Exchange getExchange(){return ExchangeBuilder.topicExchange(exchange) // 交换机类型,交换机名称.durable(true) //ture为持久化,存到磁盘,false存到内存.build();}// 创建队列@Bean("topicQueue1")public Queue getDirectQueue1(){retuen new Queue(queueName1);}// 交换机绑定队列@beanpublic Binging bindDirectQueue1(@Qualifier("topicExchange") Exchange exchange,@Qualifier("topicQueue1") Queue queue){return BindingBuilder.bind(queue).to(exchange).with(routingKey1).noargs();	}// 创建队列@Bean("topicQueue2")public Queue getDirectQueue2(){retuen new Queue(queueName2);}// 交换机绑定队列@beanpublic Binging bindDirectQueue2(@Qualifier("topicExchange") Exchange exchange,@Qualifier("topicQueue2") Queue queue){return BindingBuilder.bind(queue).to(exchange).with(routingKey2).noargs();	}}

(4)生产者发送消息

@Component
public class RabbitMqProduce {@Autowiredprivate RabbitTemplate rabbitTemplete;@value("${spring.rabbitmq.producer.queue1})private String queueName1;@value("${spring.rabbitmq.producer.queue2})private String queueName2;@value("${spring.rabbitmq.producer.routingKey2})private String routingKey1;@value("${spring.rabbitmq.producer.routingKey1})private String routingKey2;/*** 入参说明:* 第一个参数:queueName:队列名称* 第二个参数:路由键,fanout类型不需要路由键* 第三个参数:msg 消息题内容*/public void sendQueue1(String msg){rabbitTemplete.covertAndSend(queueName1,routingKey1,msg);}public void sendQueue2(String msg){rabbitTemplete.covertAndSend(queueName2,routingKey2,msg);}}

(5)消费者监听消息

@Component
public class RabbitMqListener {@RabbitListener(queues="${spring.rabbitmq.producer.queue1}")public void counsume(String msg){System.out.pringln("消费者收到 topic.queue1队列发的消息",msg);}@RabbitListener(queues="${spring.rabbitmq.producer.queue2}")public void counsume(String msg){System.out.pringln("消费者收到 topic.queue2队列发的消息",msg);}
}

(6)测试类

@SpringBootTest
public class SpringBootTest{@AUtowiredprivate RabbitMqProduce producer;@Testpublic void testSendDirectMsg(){producer.send("direct类型发送消息!!!");}
}

四 消息转换器

MQ会把消息体变成字节码
在这里插入图片描述
解决办法:使用消息转换器,实现如下:

  1. 在生产者和消费者两个服务引入依赖
<dependency><groupId>com.fasterxml.jackson</groupId><artifactId>jasckson-databind</artifactId>
</dependency>
  1. 在生产者和消费者两个服务编写消息转换器配置
@Component
public class JacksonMessageConvertor{@Beanpublic MessageCoverter jacksonMessageConvertor(){return new Jackson2JsonMessageConverter();}
}
  1. 消息体
    对于生产者来说,是map类型的,则生成者接收的时候也是map类型
    例如:
@Component
public class RabbitMqListener {@RabbitListener(queues="${spring.rabbitmq.producer.queue1}")public void counsume(Map<String,Objecct> msg){System.out.pringln("消费者收到 topic.queue1队列发的消息",msg);}}

五 案例演示

支付服务支付成功后通知交易服务进行后续操作
在这里插入图片描述
生产者和消费者两个服务都需要进行1,2,3步骤

  1. 添加依赖
<!--mq依赖-->
<dependency><groupId>org.springframework.book</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--消息转换器依赖-->
<dependency><groupId>com.fasterxml.jackson</groupId><artifactId>jasckson-databind</artifactId>
</dependency>
  1. 添加MQ配置信息
spring:rabbitmq:host: 192.168.150.101 #主机ipport: 5672 #端口virtual-host: /hmall #虚拟主机username: hmall #用户名password: 123 #密码exchange: pay.topicqueue: mark.order.pay.queueroutKingKey: pay.success
  1. 消息转换器配置类
@Component
public class JacksonMessageConvertor{@Beanpublic MessageCoverter jacksonMessageConvertor(){return new Jackson2JsonMessageConverter();}
}
  1. 生产者
    (1)生产者的配置
@Component
public class Rabbitroducer {@Autowiredprivate RabbitTemplate rabbitTemplete;@value("${spring.rabbitmq.queue})private String queueName;@value("${spring.rabbitmq.routingKey})private String routingKey;/*** 入参说明:* 第一个参数:queueName:队列名称* 第二个参数:路由键,fanout类型不需要路由键* 第三个参数:msg 消息题内容*/public void sendMsg(String msg){// 发送消息rabbitTemplete.covertAndSend(queueName,routingKey, msg);}
}

(2)业务代码支付成功发送消息

public class payOrderServiceImpl impletement PayOrderService{@Autowridprivate RabbitProducer payProducer;@Overirid@Transactional(rollback = Exception.class)public void payOrder(PayOrderDto payOrder){// 一些列操作最终交易成功// 发送消息通知try{payProducer.send(payOrder.getId());}catch(AmqpException e){log.error("交易成功,发送消息异常:{}",e.getMessages(););}}
}
  1. 消费者
@Component
public class PaySatusListener {@Autowiredprivate OrderService orderService;@RabbitListener(bindings = @QueueBinding(value = Queue(name="${spring.rabbitmq.queue}",durable="true"),exchange = @Exchange(name="${spring.rabbitmq.exchange)",type=ExchangeType.TOPIC),key = {"${spring.rabbitmq.routingKey}"}	))public void listenOrderPay(Long orderId){//标记订单为已支付orderService.markOrderPaySuccess(orderId);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/131136.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JS逆向爬虫---请求参数加密① 【某度翻译】

接口定位 抓包输入翻译关键词 全局搜索关键词,定位到接口https://fanyi.baidu.com/v2transapi 全局搜索sign 多次尝试定位变化参数sign 断点调试b函数 复制整个function&#xff0c;并测试函数运行结果。 需要把function改写成如下的数据&#xff1a; function(t) {var o…

使用Java工作流简单介绍

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

WebSocket: 实时通信的理解与认识

介绍&#xff1a; 在现代Web应用程序中&#xff0c;实时通信对于提供即时更新和交互性至关重要。传统的HTTP协议虽然适合请求-响应模式&#xff0c;但对于需要频繁数据交换的场景并不理想。而WebSocket技术的出现填补了这个空白&#xff0c;为Web开发者们带来了一种高效、实时的…

reactor(百万并发服务器) - 2

这是连续剧般的文章&#xff0c;请关注&#xff0c;持续更新中... 系列文章: http://t.csdnimg.cn/Os83Qhttp://t.csdnimg.cn/Os83Q这篇文章将我们的reactro转变成http服务器... HTTP HTTP介绍 HTTP是一个基于TCP通信协议的基础上的应用层协议。接下来我们需要解析HTTP请求消息…

【2024最新】PE工具箱【下载安装】零基础到大神【附下载链接】

下载链接&#xff1a;点这里 1.PE (Portable Executable) 工具箱通常用于处理Windows可执行文件和动态链接库&#xff08;DLL&#xff09;的二进制文件格式。这些工具对于进行逆向工程、软件分析和系统维护等任务非常有用。以下是PE工具箱的一些常见功能和用法&#xff1a; 查…

VR博物馆:让博物馆传播转化为品牌影响力

随着VR技术的不断进步&#xff0c;VR全景技术已经成为了文化展示和传播的一项重要工具&#xff0c;相较于传统视频、图文等展现方式&#xff0c;VR全景体验更加直观、便捷&#xff0c;其中蕴涵的信息量也更加丰富&#xff0c;这也为公众了解博物馆和历史文化带来了更为深刻的体…

洗衣洗鞋柜洗衣洗鞋小程序

支持&#xff1a;一键投递、上门取衣、自主送店、多种支付方式 TEL: 17638103951(同V) -----------------用户下单-------------- -------------------------多种支付和投递方式------------------------- -----------------商家取鞋--------------

Transformer的最简洁pytorch实现

目录 前言 1. 数据预处理 2. 模型参数 3. Positional Encoding 4. Pad Mask 5. Subsequence Mask 6. ScaledDotProductAttention 7. MultiHeadAttention 8. FeedForward Networks 9. Encoder Layer 10. Encoder 11. Decoder Layer 12. Decoder 13. Transformer 1…

基于STM32HAL库看门狗(独立看门狗)-简述

目录 概述 一、开发环境 二、STM32CubeMx配置 三、编码 四、运行结果 五、总结 概述 一个成熟靠谱的项目&#xff0c;离不开“看门狗”的必选项&#xff0c;凡是人写的程序多少都会有出现bug的情况&#xff08;或芯片外设受外界干扰导致故障程序卡死、跑飞的情况&#xf…

Could not find org.jetbrains.kotlin:kotlin-stdlib-jre7:1.5.21.

前两天下了一个demo&#xff0c;运行时候报了一个这样的错&#xff0c;特此记录一下。 先看下报的错。 Caused by: org.gradle.internal.resolve.ModuleVersionNotFoundException: Could not find org.jetbrains.kotlin:kotlin-stdlib-jre7:1.5.21. Searched in the following…

AI:58-基于深度学习的猫狗图像识别

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

mongodb如何删除数据并释放空间

mongodb删除数据后不会直接释放内存空间&#xff0c;是因为使用了一种称为“延迟删除”的策略。这意味着当一个文档被删除时&#xff0c;它仍然会占用一定的内存空间&#xff0c;直到这个空间被垃圾回收器&#xff08;Garbage Collector&#xff09;回收。 删除数据操作前建议先…

算法通关村第一关——链表青铜挑战笔记

1.理解Java是如何构造出链表的 public class LinkedList<T> {// 节点类class Node {// 数据域 存储数据T data;// 指针域 下一个节点的引用Node next;public Node(T data) {this.data data;}}// 头节点private Node head;// 链表长度private int size;// 构造方法publi…

【LeetCode】每日一题 2023_11_5 重复的DNA序列

文章目录 刷题前唠嗑重复的DNA序列题目描述代码和解题思路偷看大佬题解结语 刷题前唠嗑 LeetCode? 启动&#xff01;&#xff01;&#xff01; 重复的DNA序列 题目链接&#xff1a;187. 重复的DNA序列 题目描述 代码和解题思路 func findRepeatedDnaSequences(s string) …

阿里云国际站和华为云国际站之间该如何选择?

阿里云国际站和华为云国际站都是知名的云计算服务提供商&#xff0c;它们各自具有一些独特的优势和劣势。以下是它们之间的一些对比&#xff0c;九河云根据不同的使用场景提供的建议&#xff1a; 阿里云国际站&#xff1a; 优势&#xff1a; 全球覆盖&#xff1a;阿里云国际…

基于SpringBoot+Vue的旅游系统、前后端分离

博主24h在线&#xff0c;想要源码文档部署视频直接私聊&#xff0c;低价有偿&#xff01; 基于SpringBootVue的旅游系统、前后端分离 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI 工具&#xff1a;IDEA/Eci…

使用脚手架创建项目,使用组件开发

单文件组件 单文件组件就是一个文件对应一个组件, 单文件组件的名字通常是xxx.vue(命名规范和组件名的命名规范相同),这个文件是Vue框架规定的只有它能够认识&#xff0c;浏览器无法直接打开运行 Vue框架可以将xxx.vue文件进行编译为浏览器能识别的html js css的代码 xxx.vu…

蒙哥马利算法模乘(四)

一 蒙哥马利算法模乘介绍 蒙哥马利模乘算法主要为了进行大数运算a*b mod n,在介绍蒙哥马利模乘之前,先让我们来了解蒙哥马利约减。 1.1 蒙哥马利约减 a mod n 如果a是一个2048位的整数,n是一个1024位的整数,如果直接采用相除的方式,不论在空间还是时间上都会产生非常大…

Swift 和 Python 两种语言中带关联信息错误(异常)类型的比较

0. 概览 如果我们分别在平静如水、和谐感人的 Swift 和 Python 社区抛出诸如“Python 是天下最好的语言…” 和 “Swift 是宇宙第一语言…”之类的言论会有怎样的“下场”&#xff1f; 我们并不想对可能发生的“炸裂”景象做出什么预测&#xff0c;也无意比较 Swift 与 Pytho…

安吉寻梦桃花原

安吉——西湖边的那片竹海 安吉县&#xff0c;地处浙江西北部&#xff0c;湖州市辖县之一&#xff0c;北靠天目山&#xff0c;面向沪宁杭。建县于公元185年&#xff0c;县名出自《诗经》“安且吉兮”之意。 安吉县生态环境优美宜居&#xff0c;境内“七山一水二分田”&#xf…