Message queue 消息队列--RabbitMQ 【基础入门】

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

                    🏅我是平顶山大师,一个在CSDN分享笔记的博主。📚📚

    🌟推荐给大家我的博客专栏《Message queue 消息队列--RabbitMQ 【基础入门】》。🎯🎯

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

目录

一,Message queue介绍:

二,RabbitMQ介绍:

2.1什么是RabbitMQ?

2.2RabbitMQ组成?

2.3RabbitMQ工作原理

2.4RabbitMQ在企业项目中使用场景:

2.5Docker安装部署RabbitMQ

2.6创建springboot项目嵌套RabbitMQ

传递字符串类型

传递实体类型

访问测试:


一,Message queue介绍:

1.1使用消息队列的优点:

服务之间最常见的通信方式是直接调用彼此来通信,消息从一端发出后立即就可以达到另一端,称为即时消息通讯(同步通信) 消息从某一端发出后,首先进入一个容器进行临时存储,当达到某种条件后,再由这个容器发送给另一端,称为延迟消息通讯(异步通信)

如下:如果我们不使用MQ的话由订单直接调用其他的方法就会有几个问题:

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

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

解决:需要一个消息中间件,来实现解耦和缓冲的功能.

二,RabbitMQ介绍:

2.1什么是RabbitMQ?

RabbitMQ是一个功能强大的消息队列中间件,被广泛应用于分布式系统、微服务架构和异步任务处理等场景。它提供了丰富的特性和灵活的配置选项,能够满足各种不同的需求。同时也有其他的MQ,RabbitMQ只是消息队列的一种。

2.2RabbitMQ组成?
  1. 消息队列:消息队列是一种在应用程序之间进行异步通信的方式。发送方将消息发送到队列,接收方从队列中接收消息并进行处理。这种方式能够解耦发送方和接收方,提高系统的可靠性和可扩展性。

  2. AMQP协议:RabbitMQ使用AMQP(Advanced Message Queuing Protocol)作为消息传递的协议。AMQP是一个标准化的消息传递协议,支持多种编程语言和操作系统。

  3. 生产者和消费者:RabbitMQ中的消息发送方称为生产者,消息接收方称为消费者。生产者将消息发送到队列中,而消费者则从队列中接收并处理消息。

  4. 队列:队列是RabbitMQ中存储消息的地方。消息会被顺序写入队列,并按照先进先出的原则进行处理。

  5. 交换机:交换机是RabbitMQ中消息的路由器,它决定了消息应该发送到哪个队列。根据不同的路由策略,交换机可以将消息发送到一个或多个队列。

  6. 绑定:绑定是将交换机和队列关联起来的过程。绑定可以指定特定的路由规则,从而让交换机将消息发送到指定的队列。

  7. 路由策略:RabbitMQ支持多种路由策略,包括直接路由、主题路由和扇形路由等。不同的路由策略适用于不同的场景,可以实现灵活的消息路由。

  8. 可靠性:RabbitMQ提供了多种机制来确保消息的可靠传递,包括持久化、确认机制和发布者确认等。这些机制可以防止消息丢失或重复消费。

2.3RabbitMQ工作原理

RabbitMQ的工作原理主要基于生产者-消费者模型和消息队列。以下是其基本的工作流程:

生产者:生产者是创建消息的应用程序。它创建消息并发送到RabbitMQ。

队列:队列是RabbitMQ的内部结构,用于存储消息。多个生产者可以发送消息到一个队列,多个消费者可以从一个队列中获取消息。

交换器:生产者发送消息到交换器(Exchange),然后交换器根据一定的规则(路由键)将消息路由到一个或多个队列。RabbitMQ提供了几种类型的交换器,如直接交换器、主题交换器、头交换器和扇出交换器。

消费者:消费者是接收消息的应用程序。消费者连接到RabbitMQ并订阅一个队列,当新的消息到达队列时,RabbitMQ会将消息推送给消费者,或者消费者可以主动从队列中拉取消息。

消息确认:当消费者处理完一个消息后,它需要向RabbitMQ发送一个确认,告诉RabbitMQ这个消息已经被处理,可以从队列中删除。如果消费者处理消息时发生错误,它可以发送一个拒绝,告诉RabbitMQ这个消息没有被正确处理。

持久化:为了防止消息丢失,RabbitMQ提供了消息持久化的功能。生产者在发送消息时可以设置消息为持久化,RabbitMQ会将这些消息存储到磁盘,即使RabbitMQ服务器重启,这些消息也不会丢失。

通过这种方式,RabbitMQ可以在分布式系统中实现消息的可靠传递。 

RabbitMQ是一个实现了AMQP(Advanced Message Queuing Protocol)高级消息队列协议的消息队列服务,用Erlang语言.

Server(Broker):接收客户端连接,实现AMQP协议的消息队列和路由功能的进程.
Virtual Host:虚拟主机的概念,类似权限控制组,一个Virtual Host里可以有多个Exchange和Queue.
Exchange:交换机,接收生产者发送的消息,并根据Routing Key将消息路由到服务器中的队列Queue.
ExchangeType:交换机类型决定了路由消息行为,
RabbitMQ中有三种类型Exchange,分别是fanout、direct、topic.
Message Queue:消息队列,用于存储还未被消费者消费的消息. Message:由Header和body组成,Header是由生产者添加的各种属性的集合,包括Message是否被持久化、优先级是多少、由哪个Message Queue接收等.body是真正需要发送的数据内 容.
BindingKey:绑定关键字,将一个特定的Exchange和一个特定的Queue绑定起来.

2.4RabbitMQ在企业项目中使用场景:

有一个商城项目,可以使用RabbitMQ来实现以下场景:

  1. 异步订单处理:当用户下单后,可以将订单信息封装成消息发送到订单队列中。然后由消费者异步地进行订单处理,例如库存扣减、物流跟踪等。这样可以提高系统的响应速度和可靠性。

  2. 库存同步:在商城项目中,库存是一个重要的资源。可以使用RabbitMQ来实现库存同步,例如将库存变更的消息发送到库存队列中,然后由消费者将库存信息同步到数据库中。

  3. 商品推荐:在商城项目中,推荐系统是一个重要的组件。可以使用RabbitMQ来实现商品推荐的场景,例如将用户浏览历史封装成消息发送到推荐队列中,然后由推荐引擎进行商品推荐。

  4. 优惠券发放:在商城项目中,优惠券是一种常见的促销方式。可以使用RabbitMQ来实现优惠券的发放,例如将优惠券信息封装成消息发送到优惠券队列中,然后由消费者将优惠券发放给符合条件的用户。

  5. 日志收集:商城项目通常需要进行大量的日志记录和统计。可以使用RabbitMQ来实现日志收集,例如将日志信息封装成消息发送到日志队列中,然后由消费者对日志进行分类、统计和分析。

2.5Docker安装部署RabbitMQ

下载镜像:

docker pull rabbitmq:management
docker run -d \ --name my-rabbitmq \-p 5672:5672 -p 15672:15672 \-v /home/rabbitmq:/var/lib/rabbitmq \ --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的一个重要注意事项是它根据所谓的 “节点名称” 存储数据,默认为主机名)

-p:这里有两个端口

-e:指定环境变量: RABBITMQ_DEFAULT_VHOST:默认虚拟机名 RABBITMQ_DEFAULT_USER:默认的用户名

RABBITMQ_DEFAULT_PASS:默认用户名的密码

执行流程:用于在Docker中运行RabbitMQ的命令。它会创建一个名为"my-rabbitmq"的容器,并映射5672和15672端口到主机上,分别用于AMQP和管理界面访问。容器的数据存储在主机的"/home/rabbitmq"目录下,RabbitMQ的默认虚拟主机为"my_vhost",默认用户名和密码为"admin"。容器会在Docker启动时自动重启。

查看my-rabbitmq是否在运行:

docker logs my-rabbitmq

2.6创建springboot项目嵌套RabbitMQ

创建两级父子项目,父项目为maven项目mq1,子项目为springboot项目有两个provider,consumer

修改application的配置

consumer.application

server:port: 9999
spring:application:name: xxrabbitmq:host: 192.168.124.131username: springbootpassword: 123456port: 5672virtual-host: my_vhost

provider.application

server:port: 8888
spring:application:name: xxrabbitmq:host: 192.168.124.131username: springbootpassword: 123456port: 5672virtual-host: my_vhost

这是一个创建MQ的方法

@Configuration
@SuppressWarnings("all")
public class RabbitConfig {
@Bean
public Queue firstQueue() {
return new Queue("firstQueue");
}
}
Queue("firstQueue");是内置方法

firstQueue是消息队列的名字。

导入指定的包:

AmqpTemplate pom文件中引入了

    @Autowiredprivate AmqpTemplate rabbitTemplate;@RequestMapping("/sender")@ResponseBodypublic String sendFirst() {rabbitTemplate.convertAndSend("firstQueue", "Hello World");return "zhu";}
传递字符串类型

访问:localhost:8888/sender

报错:Connection refused: connect

解决添加连接的账号密码:

检查:

继续访问:localhost:8888/sender

成功:

构建消费者 Consumer

传递实体类型

使用了@Autowired注解来自动注入AmqpTemplate和ObjectMapper对象。AmqpTemplate是Spring提供的一个操作RabbitMQ的工具,可以用来发送和接收消息。ObjectMapper是Jackson库提供的一个工具,可以用来将对象转换为JSON字符串,或者将JSON字符串转换为对象。
sender02方法创建了一个User对象,然后使用ObjectMapper将这个对象转换为JSON字符串,然后发送这个JSON字符串到名为secondQueue的队列中。消费者会接收指定的队列消息使用了log.warn来打印接收到的消息从而消费。

    @RequestMapping("/sender2")@ResponseBodypublic String sender2() {com.example.provide.User user = new com.example.provide.User("1", "1");rabbitTemplate.convertAndSend("secondQueue", user);return "zhu2";}

package com.example.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;@SuppressWarnings("all")
@Component
@Slf4j
@RabbitListener(queues = "firstQueue")
public class SecondReceiver {@RabbitHandlerpublic void send(User user) {log.warn("接收到:" + user);}}

这里显示不能够这样传递:

原因是

 SimpleMessageConverter 这个类时,接收到了不支持的消息类型。SimpleMessageConverter 只支持 String、byte[] 和 Serializable 类型的消息内容

根据异常信息,你传递给它的消息内容是 com.example.provide.User 类型,因此引发了这个异常。你需要将消息内容转换为 SimpleMessageConverter 支持的类型。

生产者:

    @RequestMapping("/sender2")@ResponseBodypublic String sender2() throws JsonProcessingException {User user = new User("1", "1");// 序列化对象转换为JSON字符串String json = objectMapper.writeValueAsString(user);rabbitTemplate.convertAndSend("secondQueue", json);return "zhu2";}

实体:注意实现Serializable

package com.example.provide;import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.NoArgsConstructor;import java.io.Serializable;@SuppressWarnings("all")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private String username;
private String userpwd;
}

访问响应:

    @RequestMapping("/sender2")@ResponseBodypublic String sender2() throws JsonProcessingException {User user = new User("1", "1");// 序列化对象转换为JSON字符串String json = objectMapper.writeValueAsString(user);rabbitTemplate.convertAndSend("secondQueue", json);return "zhu2";}

消费者:

@Component
@Slf4j
@RabbitListener(queues = "secondQueue")
public class SecondReceiver {@Autowiredprivate ObjectMapper objectMapper;@RabbitHandlerpublic void send(String json) throws JsonProcessingException {User user = objectMapper.readValue(json, User.class);// 处理user对象log.warn("接收到:" + user.toString());}

实体:注意实现Serializable

package com.example.consumer;import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;import java.io.Serializable;@SuppressWarnings("all")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private String username;
private String userpwd;
}

@Component
@Slf4j
@RabbitListener(queues = "secondQueue")
public class SecondReceiver {@Autowiredprivate ObjectMapper objectMapper;@RabbitHandlerpublic void send(String json) throws JsonProcessingException {User user = objectMapper.readValue(json, User.class);// 处理user对象log.warn("接收到:" + user.toString());}

访问测试:

总结:

为什么使用消息队列?

答:1.业务解耦,2实现异步,3.流量削峰填谷(时间换空间)

消息队列:同步与异步差异
    同步:
        优点:时效性强,立即得到结果
        缺点:1.耦合度高(加业务导致改代码困难)
、                2.性能:每次执行调用需要等待上一个进程走完之后才进行
                    3.cpu资源浪费,等待需要执行后再执行
                    4.练级失败,一个服务或者进程甭溃,会导致集体阵亡

    异步:
         优点:1.降低耦合度,2.cpu资源运用合理,3.流量削峰填谷(时间换空间)
         缺点:效率没有同步高

                认真写博客的人,见一个少一个🤩🤩🤩🤩🤩🤩🤩🤩🤩

                           👍 点赞支持,⭐️ 收藏学习,❤️ 关注不迷路~
                                            💬 如有错漏请不吝指正~

平顶山大师-CSDN博客
https://blog.csdn.net/m0_73647713?spm=1011.2266.3001.5343

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

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

相关文章

Docker进阶篇-安装MySQL主从复制

一、MySQL主服务器 1、新建主服务器容器实例3307 docker run -p 3307:3306 \--name mysql-master \--privilegedtrue \-v /mydata/mysql-master/log:/var/log/mysql \-v /mydata/mysql-master/data:/var/lib/mysql \-v /mydata/mysql-master/conf:/etc/mysql \-e MYSQL_ROOT_…

Linux编辑器---vim

目录 1、vim的基本概念 2正常/普通/命令模式(Normal mode) 2、1命令模式下一些命令(不用进入插入模式) 3插入模式(Insert mode) 4末行/底行模式(last line mode) 4、1底行模式下的一些命令 5、普通用户无法进行sudo提权的解决方案 6、vim配置问题 6、1配…

基于 Redis 实现高性能、低延迟的延时消息的方案演进

1、前言 随着互联网的发展,越来越多的业务场景需要使用延迟队列。比如: 任务调度:延时队列可以用于任务调度,将需要在未来某个特定时刻执行的任务放入队列中。消息延迟处理: 延时队列可以用于消息系统,其中一些消息需要在一段时间后才能被消…

RK3568平台 HDMI交换机芯片PI3HDX231

一.简介 HDMI交换机芯片是一款可以同时输入几路HDMI的芯片,通过设计交换机芯片的寄存器值,已选择 其中一路作为输出。 I3HDX231是3:1 HDMI线性ReDriver交换机,支持每通道6 Gbps的数据速率,4096 x 2160像素分辨率,彩色…

Python项目——搞怪小程序

1、介绍 使用python编写一个小程序,回答你是猪吗。 点击“是”提交,弹窗并退出。 点击“不是”提交,等待5秒,重新选择。 并且隐藏了关闭按钮。 2、实现 新建一个项目。 2.1、设计UI 使用Qt designer设计一个UI界面&#xff0c…

深入解析JavaScript中箭头函数的用法

🧑‍🎓 个人主页:《爱蹦跶的大A阿》 🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 箭头函数(Arrow function)是JavaScript ES6中引入的一大特性。箭头函…

739.每日温度 496.下一个更大元素 I

739.每日温度 496.下一个更大元素 I 739.每日温度 力扣题目链接(opens new window) 请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位…

Android Matrix绘制PaintDrawable设置BitmapShader,手指触点为圆心scale放大原图,Kotlin(二)

Android Matrix绘制PaintDrawable设置BitmapShader,手指触点为圆心scale放大原图,Kotlin(二) 在 Android Matrix绘制PaintDrawable设置BitmapShader,手指触点为圆心scale放大原图,Kotlin-CSDN博客 基础上&…

操作系统——进程管理篇

操作系统——进程管理篇(王道23年版) 2.1_1_进程的概念、组成、特征 1.进程的概念 程序:是静态的,就是个存放在磁盘里的可执行文件,就是一系列的指令集合 进程:是动态的,是程序的一次执行过…

使用 Swift 代码优化项目编译速度

引言 软件的性能是评价一个软件质量的重要指标,尤其在今天这个时代,性能已成为大型项目不可或缺的考虑因素之一。对于用户量极大的软件,如网银系统、在线购物商城等,更是必须保证其高效稳定的性能。在这种背景下,优化…

学习笔记应用——创建用户账户并且拥有自己的信息

一、创建用户账户 将建立一个用户注册和身份验证系统,让用户能够注册账户,进而登录和注销。我们将创建一个新的应用程序,其中包含与处理用户账户相关的所有功能。 创建user 我们首先使用命令 startapp 来创建一个名为 users 的应用程序&…

大语言模型无代码构建知识图谱概述

2023年3月15日,ChatGPT4.0的横空出世,将人们对大语言模型的关注推到了风口浪尖。由于其在智能问答、翻译以及文本生成等工作任务上的卓越表现,业界一度出现了不再需要发展知识图谱相关技术的观点,知识图谱相关概念严重受挫。无可置…

如何有效防爬虫?一文讲解反爬虫策略

企业拥抱数字化技术的过程中,网络犯罪分子的“战术”也更难以觉察,并且这些攻击越来越自动化和复杂,也更加难以觉察。在众多攻击手段中,网络爬虫是企业面临的主要安全挑战。恶意爬虫活动可能导致数据滥用、盗窃商业机密等问题&…

Spring Cloud可视化智慧工地大数据云平台源码(人、机、料、法、环五大维度)

智慧工地平台是依托物联网、互联网、AI、可视化建立的大数据管理平台,是一种全新的管理模式,能够实现劳务管理、安全施工、绿色施工的智能化和互联网化。围绕施工现场管理的人、机、料、法、环五大维度,以及施工过程管理的进度、质量、安全三…

5、交叉验证

交叉验证 在本教程中,您将学习如何使用交叉验证来更好地衡量模型的性能。 本课程所需数据集夸克网盘下载链接:https://pan.quark.cn/s/9b4e9a1246b2 提取码:uDzP 文章目录 1、简介2、什么是交叉验证3、什么时候应该使用交叉验证?4、举例1)加载数据集2)创建管道3)获取MAE…

【轮式平衡机器人】——软硬件配置/准备

本系列以轮式平衡移动机器人为例,将使用基于模型设计(MBD)方法进行介绍,涉及基础硬件、软件、控制算法等多方面内容,结合MATLAB/Simulink的强大仿真能力和代码生成能力辅助设计!在此过程中可以系统了解开发…

禅道下载安装

文章目录 一、禅道官网二、安装三、管理员操作四、产品操作五、项目经理操作六、测试操作七、泳道图 一、禅道官网 官网:http://www.zentao.net/ 自己用的话是:开源版 然后一直往下滑,找到windows,此处是最新版本 二、安装 本作者就用以前…

【好文翻译】JavaScript 中的 realm 是什么?

本文由体验技术团队黄琦同学翻译。 原文链接: https://weizmangal.com/2022/10/28/what-is-a-realm-in-js/ github仓库地址: https://github.com/weizman/weizman.github.io/blob/gh-pages/_posts/2020-02-02-what-is-a-realm-in-js.md 前言 作为我对…

力扣36. 有效的数独

模拟 思路: 使用三个哈希表来存储数字个数 row[r][val] 用于存储第 r 行 val 1 的个数;column[c][val] 用于存储第 c 列 val 1 的个数; subboxes[i][j][val] 用于存储第 i 行、第 j 列个小九宫格 val 1 的个数,其中&#xff1…

rust获取本地外网ip地址的方法

大家好,我是get_local_info作者带剑书生,这里用一篇文章讲解get_local_info的使用。 get_local_info是什么? get_local_info是一个获取linux系统信息的rust三方库,并提供一些常用功能,目前版本0.2.4。详细介绍地址&a…