【RabbitMQ】快速入门及基本使用

一、引言

1、、消息队列

Ⅰ、什么是消息队列?

        消息队列是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的数据,包含发生的时间,输入设备的种类,以及特定的输入参数。也就是说:消息的发送者和接收者不需要同时与消息队列交互。消息会保存在队列中,直到接收者取回它。

Ⅱ、Message queue 释义

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

Ⅲ、消息队列特点

  1. 异步性:消息队列允许发送者发送消息后继续其它任务,而不需要等待接收者的响应。这种异步性能够提高系统的吞吐量和响应速度。
  2. 解耦性:消息队列将发送者和接收者解耦,使它们不需要知道彼此的存在。发送者只需将消息发送到队列中,而不需要关心谁将接收该消息。接收者通过订阅队列来获取消息,而不需要关心消息的发送者。这种解耦性能够提高系统的可扩展性和可维护性。
  3. 可靠性:消息队列通常具有持久化机制,可以确保消息的可靠性传输。即使在发送者或接收者出现故障的情况下,消息也不会丢失。此外,消息队列还具有消息重试和消息确认等机制,确保消息能够被正确处理。
  4. 消息类型和格式:消息队列中的消息是有类型的,并且具有格式。这使得消息可以被按类型读取,并遵循一定的格式。
  5. 多进程支持:消息队列允许一个或多个进程向它写入或者读取消息。
  6. 数据持久性:当从消息队列中读出消息后,消息队列中对应的数据都会被删除,确保数据不会重复消费。
  7. 分布式特性:通过对消费者的横向扩展,降低了消息队列阻塞的风险,以及单个消费者产生单点故障的可能性。

Ⅳ、好处

  1. 高吞吐量:由于消息的传输速度比普通的文件快,所以能够实现高吞吐量。
  2. 支持异步操作:一个线程在处理完自己的任务之后,可以把结果发送到另一个线程。
  3. 支持并发操作:多个线程可以同时处理消息队列中的消息。
  4. 支持分布式系统:由于消息队列的解耦特性,分布式系统中的组件可以独立扩展。
  5. 提供数据持久化机制:消息队列可以将数据进行持久化,确保数据不会因为处理过程中的失败而丢失。
  6. 提供错误恢复机制:当系统的一部分组件失效时,消息队列可以保证即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
  7. 提高响应速度:通过异步处理,消息队列可以显著提高系统的响应速度。
  8. 解耦:在项目启动之初来预测将来项目会碰到什么需求是极其困难的。使用消息队列可以在处理过程中间插入一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口。这允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
  9. 扩展性:由于消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可。
  10. 灵活性:使用消息队列能够使关键组件顶住增长的访问压力,而不是因为超出负荷的请求而完全崩溃。
  11. 可恢复性:当体系的一部分组件失效时,不会影响到整个系统。
  12. 送达保证:消息队列提供的冗余机制保证了消息能被实际的处理,只要一个进程读取了该队列即可。
  13. 排序保证:在许多情况下,数据处理的顺序都很重要。消息队列能保证数据会按照特定的顺序来处理。
  14. 缓冲:在任何重要的系统中,都会有需要不同的处理时间的元素。例如,加载一张图片比应用过滤器花费更少的时间。消息队列通过一个缓冲层来帮助任务最高效率的执行——写入队列的处理会尽可能的快速,而不受从队列读的预备处理的约束。该缓冲有助于控制和优化数据流经过系统的速度。
  15. 理解数据流:在一个分布式系统里,要得到一个关于用户操作会用多长时间及其原因的总体印象,是个巨大的挑战。消息系列通过消息被处理的频率,来方便的辅助确定那些表现不佳的处理过程或领域,这些地方的数据流都不够优化。
  16. 异步通信:很多时候,你不想也不需要立即处理消息。消息队列提供了异步处理机制,允许你把一个消息放入队列,但并不立即处理它。你想向队列中放入多少消息就放多少,然后在你乐意的时候再去处理它们。

2、消息队列相关

Ⅰ、AMQP

        一个提供统一消息服务的应用层标准高级消息队列协议,是一个通用的应用层协议 消息发送与接受的双方遵守这个协议可以实现异步通讯.这个协议约定了消息的格式和工作方式.

技术选型

3、什么是RabbitMQ

        RabbitMQ是一个开源的消息队列系统,使用Erlang语言开发,基于AMQP(高级消息队列协议)实现。它最初起源于金融系统,用于在分布式系统中存储和转发消息。RabbitMQ的主要特性包括易用性、扩展性、高可用性以及可靠性。消息队列(MQ)是一种应用程序对应用程序的通信方法,应用程序通过读写出入队列的消息来通信,而无需专用连接来链接它们。在事件驱动(发布-订阅)架构中,RabbitMQ扮演着Broker的角色。

  • 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绑定起来.

二、快速入门

1、Docker安装部署RabbitMQ

【注意】获取镜像的时候要获取management版本的,不要获取last版本的,management版本的才带有管理界面

docker pull rabbitmq:management

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

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

docker run -d \
--name 容器名\
-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

容器启动后,查看容器日志

docker logs 容器名

开启防火墙

systemctl start firewalld

开放端口

firewall-cmd --zone=public --add-port=15672/tcp --permanent
firewall-cmd --zone=public --add-port=5672/tcp --permanent

更新防火墙规则

firewall-cmd --reload

Ⅰ、配置用户

进入管理后台

密码:admin

账号:admin

http://ip:15672

创建用户

点进用户进行分配

2、springboot连接配置

Ⅰ、新建项目

 新建一个空项目,里面新建两个spring boot模块,并且导入依赖

接收者(publisher)消费者(consumer)

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

Ⅱ、配置yml

spring:
  rabbitmq:
    host: 0.0.0.0 #虚拟机开启的IP地址
    username: spring #创建的用户
    password: 123456 #用户的密码
    port: 5672
    virtual-host: my_vhost 

Ⅲ、案例一

接收一个string类型

生产者

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() {
        // 创建一个名为firstQueue的队列
        return new Queue("firstQueue");
    }
}

使用Controller 

@RestController
@SuppressWarnings("all")
public class SenderController {
    // 自动装配rabbitTemplate
    @Autowired
    private AmqpTemplate rabbitTemplate;

    // 发送消息到firstQueue队列
    @RequestMapping("/sendFirst")
    public String sendFirst() {
        // 将消息转换并发送到firstQueue队列
        rabbitTemplate.convertAndSend("firstQueue", "Hello World");
        return "🐉";
    }
}

访问http://localhost:8888/sendFirst

可以看到消息队列中有了一个

消费者

@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues = "firstQueue")
public class Receiver {
    @RabbitHandler
    public void process(String msg) {
        log.warn("接收到:" + msg);
    }
}

运行之后可以看到我们发送的消息

Ⅳ、案例二

我们接受一个实体类

生产者(publisher)

新建一个实体类User 实现接口Serializable

@SuppressWarnings("all")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private String username;
private String userpwd;
}

RabbitConfig 类里面添加一个队列

    @Bean
    public Queue secondQueue() {
        // 创建一个名为 secondQueue 的队列
        return new Queue("secondQueue");
    }

完整代码 RabbitConfig 

@Configuration
@SuppressWarnings("all")
public class RabbitConfig {
    @Bean
    public Queue firstQueue() {
        // 创建一个名为firstQueue的队列
        return new Queue("firstQueue");
    }

    @Bean
    public Queue secondQueue() {
        // 创建一个名为 secondQueue 的队列
        return new Queue("secondQueue");
    }
}

在Controller 层添加方法

        // 自动装配ObjectMapper
    @Autowired
    private ObjectMapper objectMapper;
// 发送消息到secondQueue队列
    @RequestMapping("/send2")
    public String send2() throws JsonProcessingException {
        // 创建一个User对象
        User wfzldr = new User("wfzldr", "1234567890");
        // 将User对象转换为json字符串
        String json = objectMapper.writeValueAsString(wfzldr);
        // 将消息转换并发送到firstQueue队列
        // 将消息转换并发送到secondQueue队列
        rabbitTemplate.convertAndSend("secondQueue", json);
        return "🐉";
    }

完整代码SenderController

@RestController
@SuppressWarnings("all")
public class SenderController {
   // 自动装配rabbitTemplate
    @Autowired
    private AmqpTemplate rabbitTemplate;
    // 自动装配ObjectMapper
    @Autowired
    private ObjectMapper objectMapper;

    // 发送消息到firstQueue队列
    @RequestMapping("/sendFirst")
    public String sendFirst() {
        // 将消息转换并发送到firstQueue队列
        rabbitTemplate.convertAndSend("firstQueue", "Hello World");
        return "🐉";
    }

    // 发送消息到secondQueue队列
    @RequestMapping("/send2")
    public String send2() throws JsonProcessingException {
        // 创建一个User对象
        User wfzldr = new User("wfzldr", "1234567890");
        // 将User对象转换为json字符串
        String json = objectMapper.writeValueAsString(wfzldr);
        // 将消息转换并发送到firstQueue队列
        // 将消息转换并发送到secondQueue队列
        rabbitTemplate.convertAndSend("secondQueue", json);
        return "🐉";
    }
}

消费者(consumer)

新建一个接受实体的Receiver

@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues = "secondQueue")
public class EntityReceiver {
    @Autowired
    private ObjectMapper objectMapper;

    @RabbitHandler
    public void process(String json) throws JsonProcessingException {
        User user = objectMapper.readValue(json, User.class);
        log.warn("接收到:" + user);
    }
}

我破门也需要在消费者里添加实体

@SuppressWarnings("all")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private String username;
private String userpwd;
}

运行两个方法

 

3、创建公共模块

在项目里面新建一个publi的公共模块,在里面写公共的实体类

在公共模块的pom.xml文件里面把打包方式war改成 jar 

在对应的消费者或者生产者里面引入对应的模块即可

        <!--        引入公共模块-->
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>public</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

我的分享就到这里,欢迎大家在评论区留言!

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

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

相关文章

一文看完String的前世今生,内容有点多,请耐心看完!

写在开头 String字符串作为一种引用类型&#xff0c;在Java中的地位举足轻重&#xff0c;也是代码中出现频率最高的一种数据结构&#xff0c;因此&#xff0c;我们需要像分析Object一样&#xff0c;将String作为一个topic&#xff0c;单独拿出来总结&#xff0c;这里面涉及到字…

虹科分享 | Redis与MySQL协同升级企业缓存

文章速览&#xff1a; MySQL为什么需要Redis EnterpriseRedis Enterprise带来哪些优势Redis Enterprise与MySQL协同 传统的MySQL数据库在处理大规模应用时已经到了瓶颈&#xff0c;Redis Enterprise怎样助力突破这一瓶颈&#xff1f;Redis Enterprise与MYSQL共同用作企业级缓存…

第二次作业+第三次作业

第二次作业第三次作业 第二次作业 题目&#xff1a; 网站需求&#xff1a; ​ 1.基于域名[www.openlab.com](http://www.openlab.com)可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c;基于[ww…

[全连接神经网络]Transformer代餐,用MLP构建图像处理网络

一、MLP-Mixer 使用纯MLP处理图像信息&#xff0c;其原理类似vit&#xff0c;将图片进行分块(patch)后展平(fallten)&#xff0c;然后输入到MLP中。理论上MLP等价于1x1卷积&#xff0c;但实际上1x1卷积仅能结合通道信息而不能结合空间信息。根据结合的信息不同分为channel-mixi…

hash应用

目录 一、位图 1.1、引出位图 1.2、位图的概念 1.3、位图的应用 1.4、位图模拟实现 二、布隆过滤器 2.1、什么是布隆过滤器 2.2、布隆过滤器应用的场景 2.3、布隆过滤器的原理 2.4、布隆过滤器的查找 2.5、布隆过滤器的插入 2.6、布隆过滤器的删除 2.7、布隆过滤器…

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

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

数字图像处理期末速成笔记

目录 一、基础知识二、相邻像素间基本关系三、图像增强方法1、直方图求解2、直方图均衡化3、直方图规定化4、图像平滑5、邻域平均法&#xff08;线性&#xff09;6、 中值滤波法&#xff08;分线性&#xff09;7、中值滤波与领域平均的异同8、4-邻域平滑法9、超限像素平滑法10、…

【Linux】yum

个人主页 &#xff1a; zxctsclrjjjcph 文章封面来自&#xff1a;艺术家–贤海林 如有转载请先通知 yum 1. 什么是yum&#xff1f;2. Linux系统(Centos)的生态3. yum的相关操作4. yum的本地配置5. 如何安装软件 1. 什么是yum&#xff1f; yum是一个软件下载安装的一个客户端&a…

逻辑运算

目录 AND OR NOT Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 逻辑运算可以保证连接多个条件&#xff0c;连接主要使用 AND、OR 、NOT完成 AND 1.查询职位不是办事员&#xff0c;但是工资低于 300 的员工信息 这个范例可以理…

学习响应式编程中遇到的奇奇怪怪的问题

spring项目无法启动 Description: Web application could not be started as there was no org.springframework.boot.web.reactive.server.ReactiveWebServerFactory bean defined in the context. Action: Check your application’s dependencies for a supported react…

Visual Studio 设置编辑框(即代码编辑器)的背景颜色

在Visual Studio 中设置编辑框&#xff08;即代码编辑器&#xff09;的背景颜色&#xff0c;可以按照以下步骤进行&#xff1a; 打开Visual Studio。在菜单栏上找到并点击“工具”(Tools)选项。在下拉菜单中选择“选项”(Options)。在“选项”对话框中&#xff0c;导航至“环境…

基于Spring+mybatis+vue的在线课后测试系统(Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

Oracle架构_数据库底层原理、机制 (授人以渔)

目录 系统全局区SGA 高速缓存缓冲区(数据库缓冲区) 日志缓冲区 共享池 其他结构 用户连接进程 用户进程User Process Server Process服务进程 程序全局区PGA Oracle的connect连接和session会话与User Process紧密相关 后台进程 数据库写入进程(DBWn) 检查点(CKPT)…

plt.table绘制表格

目录 一&#xff1a;介绍 二&#xff1a;绘制一个表格 一&#xff1a;介绍 plt.table()函数是Matplotlib库中的一个函数&#xff0c;用于在图表中插入一个表格。它提供了创建和定制表格的功能。下面是plt.table()函数的一些常用参数&#xff1a; cellText: 一个二维列表或数…

mp4文件可以转成mp3音频吗

现在是个非常流行刷短视频一个年代&#xff0c;刷短视似乎成了人们休闲娱乐的一种方式&#xff0c;在日常刷短视频过程中&#xff0c;肯定会有很多同学被短视频 bgm 神曲洗脑&#xff0c;比如很多被网红翻唱带火的歌曲&#xff0c;例如其中"不负人间”&#xff0c;就是其中…

elementUI+el-upload 上传、下载、删除文件以及文件展示列表自定义为表格展示

Upload 上传组件的使用 官方文档链接使用el-upload组件上传文件 具体参数说明&#xff0c;如何实现上传、下载、删除等功能获取文件列表进行file-list格式匹配代码 文件展示列表自定义为表格展示 使用的具体参数说明文件大小展示问题&#xff08;KB/MB&#xff09;文件下载代码…

Windows下载并配置Kettle

注意&#xff1a;需要windows配置Java 下载 Kettle 进入官网&#xff1a;https://www.hitachivantara.com/en-us/products/pentaho-plus-platform/data-integration-analytics/pentaho-community-edition.html 下载带有Pentaho Data Integration (Base Install)的文件&#…

智能工厂能耗监测系统

智能工厂能耗监测系统是一种用于监测和管理智能工厂内能耗的系统。它通过实时收集和分析能耗数据&#xff0c;帮助工厂管理者实现能源节约、提高能源使用效率和降低运营成本。本文将详细介绍智能工厂能耗监测系统的原理、组成、优势和应用。 一、系统原理 智能工厂能耗监测系…

AWS 亚马逊云服务专题学习

目录 1. 学习大纲2. 学习地址3. 系列博客4. AWS 初识 1. 学习大纲 AWS 基础知识&#xff1a;IAM、EC2、负载均衡、Auto Scaling、EBS、EFS、Route 53、RDS、ElastiCache、S3、CloudFrontAWS CLI&#xff1a;CLI 设置、在 EC2 上的使用、最佳实践、SDK、高级使用深度数据库比较…

文件名修改方法:批量重命名文件,并将扩展字母统一转换为大写

在日常生活和工作中&#xff0c;我们经常需要处理大量的文件&#xff0c;有时候需要对这些文件进行重命名&#xff0c;或者将它们的扩展名统一转换为大写。虽然这个过程看似简单&#xff0c;但实际上需要一定的技巧和注意事项。本文讲解云炫文件管理器如何批量重命名文件&#…