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
        @Autowired
        private 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格式转换为实体对象。

 消费者

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

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


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

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8全网首发:新一代高效可形变卷积DCNv4如何做二次创新?高效结合SPPF

💡💡💡本文独家改进:DCNv4更快收敛、更高速度、更高性能,与YOLOv8 SPPF高效结合 收录 YOLOv8原创自研 https://blog.csdn.net/m0_63774211/category_12511737.html?spm=1001.2014.3001.5482 💡💡💡全网独家首发创新(原创),适合paper !!! 💡💡💡…

AOI与AVI:在视觉检测中的不同点和相似点

AOI(关注区域)和AVI(视觉感兴趣区域)是视觉检测中常用的两个概念,主要用于识别和分析图像或视频中的特定区域。虽然这两个概念都涉及到注视行为和注意力分配,但它们在定义和实际应用等方面有一些差异。 AOI…

x86-x64汇编语言、反汇编知识和IDA

x86-x64汇编语言 基础知识 x86寄存器: 通用寄存器:EAX, EBX, ECX, EDX, ESI, EDI 栈顶指针寄存器:ESP 栈底指针寄存器:EBP 指令计数器:EIP 段寄存器:CS, DS, ES, FS, GS, SS x86-64寄存器:&a…

2.【C语言】(函数指针||sizeof||笔试题)

0x01.函数指针 void test(const char* str) {printf("%s\n", str); }int main() {void (*pf)(const char*) test;//pf是函数指针变量void (*pfarr[10])(const char*);//pfarr是存放函数指针的数组void (*(*p)[10])(const char*) &pfarr;//p是指向函数指针数组…

Leetcoder Day10|栈与队列part02(栈的应用)

语言:Java/C 目录 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值 今日总结 20. 有效的括号 给定一个只包括 (,),{,},[,] 的字符串,判断字符串是否有效。 有效字…

WEB接口测试之Jmeter接口测试自动化 (三)(数据驱动测试)

接口测试与数据驱动 1简介 数据驱动测试,即是分离测试逻辑与测试数据,通过如excel表格的形式来保存测试数据,用测试脚本读取并执行测试的过程。 2 数据驱动与jmeter接口测试 我们已经简单介绍了接口测试参数录入及测试执行的过程&#xff0…

Unity3D Pico VR 手势识别物体交互 适配 MRTK3

当前Pico已经支持手势识别了,但是提供的PICO Unity Integration SDK 中是没有手势和物体交互的功能,Unity XR Interaction Toolkit提供的手势识别物体交互对 Quest适配的挺好的,Pico 当前只能用指尖点触还不能对物体进行抓握以及手势控制射线…

数据结构一:算法效率分析(时间复杂度和空间复杂度)-重点

在学习具体的数据结构和算法之前,每一位初学者都要掌握一个技能,即善于运用时间复杂度和空间复杂度来衡量一个算法的运行效率。所谓算法,即解决问题的方法。同一个问题,使用不同的算法,虽然得到的结果相同,…

开发实践8_project

要求: 使用Restful对Chaos模型作基本操作。 结果: post 3 组数据后,get 查询如下: put修改后get: delete pk3之后get: 代码: python manage.py startapp pro8_app 注册 总路由 // path(pr…

免费200万Tokens 用科大讯飞API调用星火大模型服务

简介 自ChatGPT火了之后,国内的大模型发展如雨后春笋。其中的佼佼者之一就是科大讯飞研发的星火大模型,现在大模型已经更新到V3 版本,而且对开发者也是相当友好,注册就送200万tokens,讯飞1tokens 约等于 1.5 个中文汉字 或者 0.8 个英文单词…

JVM 如何判断一个对象可以被回收

Hi, 我是 浮生。 今天分享一道一线互联网公司必问的面试题。 ”JVM 如何判断一个对象可以被回收“ 关于这个问题,来看看高手的回答。 一、问题解析 在 JVM 里面,要判断一个对象是否可以被回收,最重要的是判断这个对象是否还在被…

中仕教育:省考怎么查每个岗位报考人数?一篇文章带你搞定!

参加省考避开热门岗位能够一定程度上提高上岸几率,怎么看岗位报考人数? 1. 官方公告:每年省考发布招录公告时,会公布各个岗位的招录人数,可以关注招录信息。 2. 查询报名数据:在报名结束后,省考招录机关…

debian12.4配置

文章目录 debian12.4配置概述笔记将非root用户添加到sudo组更换国内源配置ssh的客户端访问END debian12.4配置 概述 在虚拟机中装了一个debian12.4, 想配置ssh客户端连接, 出了问题. 配置乱了, 还好长了个心眼, 做了快照. 发现2个问题: debian12.4默认安装完, 有ssh, 先检查…

Python自动化测试【selenium面试题】

一、selenium中如何判断元素是否存在? expected_conditions模块提供了16种判断方法,以下方法是判断元素存在DOM中: presence_of_element_located """ An expectation for checking that an element is present on the DOM of…

【Linux】第三十一站:管道的一些应用

文章目录 一、我们之前的|(竖划线)管道二、自定义shell三、使用管道实现一个简易的进程池1.详解2.代码3.一个小bug4.最终代码 一、我们之前的|(竖划线)管道 cat test.txt | head -10 | tail -5如上代码所示,是我们之前所用的管道 我们拿下面这个举个例子 当我们用…

【SpringBoot】—— 如何创建SpringBoot工程

SpringBoot简化了Spring应用的初始搭建和开发过程。 工程创建 新建模块 出现java: 错误: 无效的源发行版:18这样的错误, 修改pom.xml文件 出现以下信息,即运行成功 修改默认端口 创建application.yml文件 内容: server:port:…

【没学过编程语言,想要做一款游戏应该怎么做?】

*** 【没学过编程语言,想要做一款游戏应该怎么做?】 想让你的创意成为像《堡垒之夜》《原神》这样引爆式的热门游戏吗? 想制作一个能与《我的世界》《模拟城市》一决高下的畅销游戏吗? 即使你手头并没有复杂的代码能力&#xf…

知识图谱KG+大模型LLM

LLM-based KG KnowLM OpenSPGKG-based RAG 基本原理 从query出发的语义解析 pre-LLM方法 思想:直接将问题解析为对应的逻辑表达式,然后到知识图谱中查询。 方法:通常包含逻辑表达式、语义解析算法、语义解析模型训练三部分。一般步骤是将问句…

【51单片机Keil+Proteus8.9+ADC0804】ADC实验 模拟转数字实验

一、实验名称 ADC实验 模拟转数字实验 二、设计思路 电路设计 1.选用AT89C51单片机作为电路核心单元,外接8位单通道AD转换器ADC0804芯片和LM016L显示器以及滑动变阻器等其它常用元器件构成电路。 2.将ADC0804芯片的控制引脚RD,WR,INTR接到AT89C51芯片对应引脚&…

管理信息系统知识点复习

目录 一、名词解释题1.企业资源规划(ERP)2.面向对象方法:3.电子健康:4.供应链5.数据挖掘6.“自上而下”的开发策略:7.业务流程重组8.面向对象:9.决策支持系统10.聚类11.集成开发环境:12.供应商协同13.数据仓库14.深度学…