RabbitMQ系列之入门级

 

  🎉🎉欢迎来到我的CSDN主页!🎉🎉

🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚

🌟推荐给大家我的博客专栏《RabbitMQ系列之入门级》。🎯🎯

🎁如果感觉还不错的话请给我关注加三连吧!🎁🎁

一、MQ的简介

1. 什么是MQ(概念简述) 

        MQ通常指的是消息队列(Message Queue),是一种用于在应用程序之间传递消息的通信方式。消息队列系统允许不同组件之间异步通信,通过在发送者和接收者之间引入队列,实现解耦和提高系统的可伸缩性

        在消息队列中,消息生产者将消息发送到队列,而消息消费者从队列中接收消息。这种异步通信的方式可以使系统中的各个组件独立运作,不需要直接依赖对方的状态,提高了系统的可维护性和可扩展性。

2. MQ的主要应用场景

         MQ的应用场景包括但不限于,下面是几个典型的几个应用场景:

MQ典型的应用场景
应用场景说明
解耦系统组件允许不同组件之间解耦,降低了组件之间的依赖性。
提高系统可靠性如果某个组件暂时不可用,消息队列可以存储消息,待组件恢复正常后再处理这些消息。
异步通信允许系统中的组件进行异步通信,提高了系统的响应性。
削峰填谷在流量波动较大的场景中,消息队列可以用来平滑流量,防止系统峰值负载。
分布式系统协调在分布式系统中,消息队列可以用来协调各个节点的工作。

3. MQ的常见实现方式

3.1 RabbitMQ

1. 特点

        RabbitMQ 是一个开源的消息队列系统,它遵循AMQP(Advanced Message Queuing Protocol)协议。它支持多种消息传递模式,包括点对点、发布/订阅和请求/响应。

2. 适用场景

        RabbitMQ适用于需要高度灵活性和多样性消息传递模式的场景,同时它的性能和可靠性也是其特点之一。

3.2 Apache Kafka 

1. 特点

        Kafka 是一个分布式的、高吞吐量的消息系统主要用于处理实时数据流。它的设计目标是具有高可用性和持久性,同时能够处理大规模的数据流。

2. 适用场景

         Kafka 适用于大规模的数据流处理,如日志收集、事件溯源、流式处理等场景。

3.3 ActiveMQ

1. 特点

        ActiveMQ 是一个基于Java的开源消息中间件,支持多种协议,包括OpenWire、STOMP、AMQP等。它提供了丰富的功能,如持久化、事务、集群等。 

2. 适用场景

         ActiveMQ适用于需要与多种协议兼容,并且对消息传递的可靠性和事务有要求的场景。

3.4 Apache RocketMQ接口

1. 特点

         RocketMQ 是由阿里巴巴开发的分布式消息中间件,具有高吞吐、低延迟、高可用性的特点。它支持丰富的消息传递模式,如顺序消息、事务消息等

2. 适用场景

         RocketMQ适用于高吞吐、低延迟要求的场景,尤其在电商、金融等领域有广泛应用。

3.5 Amazon Simple Queue Service (SQS)

1. 特点

        SQS是亚马逊提供的托管消息队列服务,具有高可用性和弹性。它支持分布式架构,并提供了简单的API用于发送和接收消息。 

2. 适用场景

        SQS适用于在AWS云上构建可扩展的、分布式的应用程序,无需担心消息队列的基础设施管理。 

3.6 Redis 发布/订阅 

1. 特点

        Redis 是一个内存数据库,但它也提供了发布/订阅(Pub/Sub)功能。Redis的消息发布/订阅是基于频道的,允许多个订阅者监听同一个频道的消息。

2. 适用场景

         Redis的Pub/Sub适用于简单的消息发布和订阅场景,尤其是对于需要快速实现的小规模应用。

         这些是一些常见的MQ实现方式,选择合适的MQ取决于应用的具体需求,包括对性能、可靠性、消息传递模式的要求等。

图解说明

4. MQ作用说明(含图解)

        假设我们在淘宝下了一笔订单后,淘宝后台需要做这些事情:

1. 消息通知系统:通知商家,你有一笔新的订单,请及时发货

2. 推荐系统:更新用户画像,重新给用户推荐他可能感兴趣的商品

3. 会员系统:更新用户的积分和等级信息

createOrder(...) {
// 完成订单服务
doCreateOrder(...);
// 调用其他服务接口
sendMsg(...);
updateUserInterestedGoods(...);
updateMemberCreditInfo(...);
}

        如上图所示,我们订单系统创建订单的时候自身需要2s的处理时间,然后要向三个系统分别发送请求并且等待他们的响应一个系统服务需要等待2是,一共需要8s。

存在问题:

        过度耦合:如果后面创建订单时,需要触发新的动作,那就得去改代码,在原有的创建订单函数末尾,再追加一行代码

        缺少缓冲:如果创建订单时,会员系统恰好处于非常忙碌或者宕机的状态,那这时更新会员信息就会失败,我们需要一个地方,来暂时存放无法被消费的消息

        这时候我们使用一个消息中间件,来实现解耦和缓冲的功能

         使用一个消息中间件可以让我们的订单系统不必等待我们其他三个系统的响应而去处理其他的事务只需要等待2s,其他系统的响应让他在后台运行,就算响应的时间很长也影响不到订单系统的工作。

二、 RabbitMQ

1. 组成部分

        RabbitMQ的主要组成部分如下:

  1. Producer(生产者):

    • 生产者是消息的发送方,负责产生并发送消息到RabbitMQ的消息队列中。生产者通常将消息发布到一个特定的交换机。
  2. Exchange(交换机):

    • 交换机是消息的分发中心,负责将消息路由到一个或多个消息队列。RabbitMQ支持不同类型的交换机,包括直接交换机、主题交换机、扇出交换机等,以支持不同的消息分发策略。
  3. Queue(消息队列):

    • 队列是消息的存储位置,生产者将消息发送到队列,而消费者从队列中接收消息。消息在队列中等待被消费。
  4. Binding(绑定):

    • 绑定是交换机和队列之间的关联关系。它定义了消息如何从交换机路由到特定的队列。生产者通过将消息发送到交换机,而消费者通过从队列接收消息来实现消息的传递。
  5. Consumer(消费者):

    • 消费者是消息的接收方,负责从消息队列中获取消息并进行处理。消费者订阅一个或多个队列,以接收交换机路由到这些队列的消息。
  6. Virtual Host(虚拟主机):

    • 虚拟主机是RabbitMQ中的逻辑隔离单位,允许在同一物理服务器上创建多个相互独立的消息中间件环境。每个虚拟主机拥有自己的交换机、队列、绑定等。
  7. Connection(连接):

    • 连接是生产者和消费者与RabbitMQ之间的网络连接。一个连接可以包含多个通道(Channel),每个通道代表一个独立的会话。连接的建立和管理是由RabbitMQ客户端库处理的。
  8. 通道(通道):

    • 通道是在连接内部的逻辑通信信道,生产者和消费者通过通道与RabbitMQ进行交互。通道的使用可以减轻连接的开销,提高性能。

 图解

三、Docker安装部署RabbitMQ

1. 拉取RabbitMQ镜像文件

        我们现在我们的虚拟机中拉取我们的一个RabbitMQ的一个镜像文件,版本拉取management的。

指令:docker pull rabbitmq:management 

2. 安装部署RabbitMq容器

        我们拉取了rabbitmq镜像文件之后我们需要去创建一个RabbitMq的容器去运行使用。

创建的命令如下:

docker run -d \
--name my-rabbitmq \
-p 5672:5672 -p 15672:15672 \
--hostname my-rabbitmq-host \
-e RABBITMQ_DEFAULT_VHOST=my_vhost \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin \
--restart=always \
rabbitmq:management

 指令说明:

--hostname:主机名(RabbitMQ的一个重要注意事项是它根据所谓的 “节点名称” 存储数据,默认为主机名)

-e:指定环境变量:

RABBITMQ_DEFAULT_VHOST:默认虚拟机名

RABBITMQ_DEFAULT_USER:默认的用户名

RABBITMQ_DEFAULT_PASS:默认用户名的密码

 

        我们创建完我们的RabbitMq容器之后我们可以输入指令: docker logs my-rabbitmq 进行一个查看日志。

         我们在网页进行访问rabbitmq的后台界面,进行登陆进入。账号和密码在创建容器时就设置好了。

         登陆进去的首页。

         这就说明我们的rabbitmq的安装和部署已经成功。

3. 配置RabbitMq

        我们在登陆进入的后台首页中右侧的Virtual host中选择我们创建容器时的主机。

         我们点击页面的Admin进入其选项,新建一个用户用于我们后续的一个操作实现,我们一般不用admin进行登陆。

        我们创建好新的用户之后,还要点击进入该用户给该用户分配我们的主机。 下面是一些后台界面的功能说明。

四、springboot连接配置RabbitMQ

1. 创建项目

        打开我们的开发工具IDEA进行创建对应的项目用户实现功能。我们新建一个空的项目。

        创建好空项目之后我们在这个空项目下创建两个Spring模块一个是发布者,一个是消费者。

2. 修改配置文件 

         我们创建好项目以及我们的两个模块后,我们在两个模块下的配置文件转换成yml的格式,以及对其配置文件进行配置。

 publisher/application.yml

server:port: 9999
spring:rabbitmq:
#      安装rabbitMq容器的虚拟机的ip地址host: 192.168.52.130#      Rabbitmq的用户账号username: yxspring
#      Rabbitmq的用户密码password: 123456
#            Rabbitmq的容器的端口号port: 5672
#       RabbitMq的主机virtual-host: my_vhost

consumer/application.yml

server:port: 8888
spring:rabbitmq:#      安装rabbitMq容器的虚拟机的ip地址host: 192.168.52.130#      Rabbitmq的用户账号username: yxspring#      Rabbitmq的用户密码password: 123456#            Rabbitmq的容器的端口号port: 5672#       RabbitMq的主机virtual-host: my_vhost

3. 案例演示

发布者

        我们配置完我们的配置文件之后,我们先发送消息到我们的RabbitMq中去,编写对应的所需的代码。在我们的发布者模块下创建一个配置类。

 RabbitConfig.java
package com.yx.publisher;import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@SuppressWarnings("all")
public class RabbitConfig {
@Bean
public Queue firstQueue() {
return new Queue("firstQueue");
}}

        我们在发布者编写完我们的配置类之后在创建一个controller类用于发送我们的消息到我们的RabbitMQ中。(注:我们没有配置类就无法向我们的RabbitMq中发送信息以及生成队列

 TestController.java
package com.yx.publisher;import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** com.yx.publisher** @author 君易--鑨* @site www.yangxin.com* @company 木易* @create 2024/1/19*/
@RestController
public class TestController {//        注入AmqpTemplate@Autowiredprivate AmqpTemplate amqpTemplate;
//        编写一个请求方法@RequestMapping("/send1")public String send1(){
//    向交换机发送消息amqpTemplate.convertAndSend("firstQueue","木易");return "木易";}}

        我们直接启动我们的发布者服务,在网页去访问我们控制类中的方法。我们多访问几次多刷新几次

        我们再去到RabbitMq后台管理界面去查看。 

消费者

        我们之前只是向我们的RabbitMq中发送消息,但我们并没有去接收RabbitMQ的消息,接下来就是接收消息。

Receiver.java
package com.yx.consumer;import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues = "firstQueue") //接收的队列
public class Receiver {
@RabbitHandler
public void process(String msg) {
log.warn("接收到:" + msg);
}
}

         我们接听的队列一定要存在否则我们访问的时候回报错,然后我们运行消费者服务,我们会自动的接受我们的RabbitMQ的消息。

         上述图片的是我们消费者接收消息控制台输出对应的结果,我们基本的接受信息的操作就实现了。

 实例讲解

         我们接下来在我们的发布者中创建一个User实体类,然后我们发起一个请求将我们的实体对应传输过去。

User.java
package com.yx.publisher;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@SuppressWarnings("all")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User{
private String username;
private String userpwd;
}

        我们创建好实体类之后我们再去到我们的Controller类中去编写一个方法发送我们的实体对应到我们的RabbitMQ上去。在编写方法之前我们先去RabbitConfig配置类中去编写一个发送实体对象的队列。

        我们在对应的消费者服务中编写一个专门接受实体对象的类,并且在消费者服务者编写对应的实体对象进行接受。

 PojoReceiver.java
package com.yx.consumer;import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues = "secondQueue") //接收的队列
public class PojoReceiver {
@RabbitHandler
public void process(User user) {
log.warn("接收到:" + user);
}
}

        编写完成之后我们重启我们的发布者服务,我们在网页测试发送实体对象的请求方法。

        我们的对象想要发送过去首先我们的对象实体类要实现序列化接口,我们在重新启动发布者服务调用对应的请求方法

 

 

        我们启动消费者进行接收信息结果会报错。

        报错的原因是因为发送的对象的名称和包名需要一致,我们如何解决呢?

 解决实体传输方案一:将对象转换成json的格式

        我们在发送之前将我们的实体对象转换成json的格式发送过去,再在消费者那边将json格式转换为实体对象的格式。

发布者

        消费者在对应的接收类中我们对其先注入ObjectMapper类,再将传输过来的json格式转换为实体对象。

 消费者

        我们再重启两个服务再进行对应的接口测试。 

        由上图可知我们成功的解决了传输实体对象的问题。 


🎉🎉本期的博客分享到此结束🎉🎉

📚📚各位老铁慢慢消化📚📚

🎯🎯下期博客博主会带来新货🎯🎯

🎁三连加关注,阅读不迷路 !🎁

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

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

相关文章

防火墙基础1

防火墙简绍 什么是防火墙? 状态防火墙工作原理? 防火墙如何处理双通道协议? 防火墙如何处理nat? 路由交换终归结底是连通性设备。 网络在远古时期没有防火墙大家都是联通的,any to any。 防御对象: 授权用户 非授权用户 防火墙是一种隔离…

存储开发入门到进阶,这几本书一定要看!!

有些朋友是已经深耕存储多年,有的朋友是刚刚入门、或者说有兴趣但是迟迟不得入门。以下从笔者的经验出发,向大家推荐几本书,可以比较系统的补充一些编程的内功和存储的基础知识,向你展示一条存储通关之路。 语言 语言是第一个要…

55. 跳跃游戏 - 力扣(LeetCode)

题目描述 给定一个非负整数数组,你最初位于数组的第一个位置。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个位置。 题目示例 输入:nums [2,3,1,1,4] 输出:true 解释:可以先跳 1 步&#x…

LFU算法

LFU算法 Least Frequently Used(最不频繁使用) Leetcode有原题,之前手写过LRU,数据结构还是习惯于用java实现,实现是copy的评论题解。 题解注释写的很清楚 大致就是说LFUCache类维护一个存放node的map,同…

基于springboot+vue的墙绘产品展示交易平台系统(前后端分离)

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 研究背景…

微信小程序商城注册是个人还是公司的?

随着移动互联网的飞速发展,微信小程序已经成为了商家们开展电子商务的重要平台之一。微信小程序商城以其便捷的操作、庞大的用户基础和较低的成本投入,吸引了众多商家的关注。然而,对于想要进入这一领域的创业者来说,一个基础性的…

C# CefSharp 输入内容,点击按钮,并且滑动。

前言 帮别人敲了个Demo,抱试一试心态,居然成功了,可以用。给小伙伴们看看效果。 遇到问题 1,input输入value失败,里面要套了个事件,再变换输入value。后来用浏览器开发工具,研究js代码,太难了&a…

Authorization Failed You can close this page and return to the IDE

一.问题描述 注册JetBrains成功,并且通过了学生认证,但在activate pycharm时,却显示Authorization Failed You can close this page and return to the IDE如上图 二.原因: 可能是因为之前使用了破解版pycharm 三.解决方法&am…

GNSS技术与无人机协同:开启未来交通新篇章

随着科技的不断发展,全球导航卫星系统(GNSS)技术与无人机技术的协同应用成为未来交通系统的引人瞩目的新方向。创新微公司在这一领域的技术创新为实现GNSS技术与无人机的紧密协同提供了新的可能性。本文将深入探讨GNSS技术与无人机协同的前景…

创新医疗服务:宠物在线问诊系统的搭建与应用

随着科技的不断进步,创新的医疗服务方式也日渐成为宠物主人关心爱宠健康的首选。本文将深入介绍如何搭建一套创新的宠物在线问诊系统,并展示其应用的技术代码。 1. 系统架构与技术选择 在开始搭建之前,我们需要设计系统的架构并选择合适的…

springboot初始项目每一层的含义

一.创建的时候主要勾选了以下 二.项目架构 三.有的项目下创建出来,存在更多不同的层级 src/main/java/com/example/demo/controller: 控制器层,包含处理 HTTP 请求和响应的控制器类。 src/main/java/com/example/demo/service: 服务层,包含业…

我每天如何使用 ChatGPT

我们都清楚互联网的运作方式——充斥着各种“爆款观点”,极端分裂的意见,恶搞和无知现象屡见不鲜。 最近,大家对于人工智能(AI)特别是大语言模型(LLMs)和生成式 AI(GenAI&#xff0…

四、arcgispro二次开发运行程序修改的地方还是没有变踩坑

对于arcgispro二次开发学习是一件充满兴趣并且具有好奇心的一件事,但是当创建了一个工程第一次调试成功,并出来了自己期待很久的一个程序后,当第二次修改并运行,发现一直没有反应,很是头疼,查了很多资料也没…

日常记帐软件,你的财务守护者

在快节奏的现代生活中,理财的重要性日益凸显。如何让每一分钱都花在刀刃上,是许多人都渴望知道的答案。今天,我要为大家介绍一款简单实用的记账软件——晨曦记账本,相信它会是你财务之路上的得力助手。 所需工具: 一…

Windows下网络编程(win32API+VS2022)

一、开发环境 我这里介绍下我用的环境安装过程。 所有版本的VS都可以的。 我当前环境是在Windows下,IDE用的是地表最强IDE VS2022。 下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/ 因为我这里只需要用到C和C语言编程,那…

C++ STL之queue的使用及模拟实现

文章目录 1. 介绍2. 队列的使用3. 队列的模拟实现 1. 介绍 英文解释: 也就是说: 队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端提取元素。 队列作为容器适配器实现&…

seldom之数据驱动

seldom之数据驱动 如果自动化某个功能,测试数据不一样而操作步骤是一样的,那么就可以使用参数化来节省测试代码。 seldom是我在维护一个Web UI自动化测试框,这里跟大家分享seldom参数化的实现。 GitHub:GitHub - SeldomQA/seld…

数据结构OJ题——二叉树前序、中序遍历非递归实现(Java版)

二叉树前序、中序遍历非递归实现 前序非递归遍历实现中序非递归遍历实现 前序非递归遍历实现 题目: 二叉树前序遍历非递归实现 总体思路:用非递归的方式模拟递归遍历。 以下图为例: 图示详解: 代码实现: /*** Defi…

【软考中级】3天擦线过软考中级-软件设计师

前提:已有数据结构、操作系统、计算机网络、数据库基础 (风险系数较高,请谨慎参考) 贴一个成绩单hhhh 弯路:很早之前有看过一遍网上的软考课程,也记录了一些笔记,然而听完还是啥都记不住。 推…

安科瑞弧光保护装置助力煤矿高压开关柜的可靠供电

摘要 在煤矿高压开关柜运行中,由于受到多种因素的干扰,中低压母线发生故障的概率较高,在中低压母线装设中又没有设置专门的保护,所以开关柜电弧光短路等问题时有发生,对变压器等设备造成一定的损害。鉴于此&#xff0c…