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。 防御对象: 授权用户 非授权用户 防火墙是一种隔离…

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

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

SpringBoot服务设置禁止server.point端口的使用

问题&#xff1a; 当项目服务引用了jar spring-boot-starter-web后 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency>所以项目一启动&#xff0c;就会使用serv…

网络中的长连接和短连接

在网络通信中&#xff0c;长连接和短连接是两种不同的连接方式。它们指的是客户端和服务器之间持续通信的时间。 短连接 短连接是一种临时性的连接&#xff0c;客户端发送请求后&#xff0c;服务器响应请求并传输数据后&#xff0c;连接会立即关闭。每次请求都需要建立一个新的…

Git将当前分支暂存切换到其他分支

在我们使用Git进行版本控制时&#xff0c;经常会遇到这样的情况&#xff1a;我们正在一个分支上进行一些修改&#xff0c;但突然需要切换到另一个分支进行一些操作。这时&#xff0c;我们可以使用git stash命令来暂存我们的修改&#xff0c;然后再切换到其他分支。下面&#xf…

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

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

LFU算法

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

go语言入门介绍 - 特征、命名、关键字、保留字、声明

Go 语言是谷歌 2009 年首次推出并在 2012 年正式发布的一种全新的编程语言&#xff0c;可以在不损失应用程序性能的情况下降低代码的复杂性。 1、优点 自带gc。静态编译&#xff0c;编译好后&#xff0c;扔服务器直接运行。简单的思想&#xff0c;没有继承&#xff0c;多态&a…

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

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

「nuxt2配置tailwindcss」nuxt2添加tailwindcss详细步骤!解决版本不对称各种报错~~复制黏贴搞定!

运行环境 node和npm使用版本 node v14.21.3 (npm v6.14.18) 1.插件下载 官方文档说明 npm install -D nuxtjs/tailwindcss3.4.3 tailwindcss3.4.1 postcss^8.4.33 autoprefixer10.4.17 2.nuxt.config.js配置 module.exports {// ...buildModules: [nuxtjs/tailwindcss],// …

spring(1):基于XML获取Bean对象以及各种依赖注入方式

1. 获取Bean XML文件&#xff1a;<bean id"helloworld" class"org.kkk.spring6.bean.HelloWorld"></bean>1.1 根据id获取 Test public void testHelloWorld(){//加载XML文件ApplicationContext context new ClassPathXmlApplicationContext…

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

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

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

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

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

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

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

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

软件工程测试3

1.【多选】关于领域类建模说法正确的是 A. 需求描述中的名词或名词短语都划分为领域概念类 B. 在类的聚合关系中&#xff0c;聚合体对象是整体&#xff0c;聚合元素对象是部分 C. 需求描述中的名词、数词、形容词等有可能是属性值 D. 在类的继承关系中&#xff0c;父类中的属性…

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

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

springboot初始项目每一层的含义

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

ardupilot开发 --- RTSP多媒体数据流(视频流) 篇

0. 一些概念 RTSP是 TCP/IP 协议体系中的一个应用层协议&#xff0c;该协议定义了一对多应用程序如何有效地通过 IP 网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上&#xff0c;它使用TCP或UDP完成数据传输。 在mission planner中查看(拉取)RTSP视频流

我每天如何使用 ChatGPT

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