SpringCloud源码探析(六)-消息队列RabbitMQ

news2024/11/26 5:18:45

1.概述

RabbitMQ是一个开源的消息代理和队列服务器,它是基于Erlang语言开发,并且是基于AMQP协议的。由于Erlang语言最初使用与交换机领域架构,因此使得RabbitMQ在Broker之间的数据交互具有良好的性能。AMQP(Advanced Message Queuing Protocol,高级消息队列协议)是一种消息队列应用层协议,专门面向消息的中间件而设计,类似于JAVA的JMS协议,基于此规范能够开发出各种各样的消息中间件。RabbitMQ能够与SpringAMQP完美整合,具有较强的扩展性和丰富的API,且具有高可靠性和低延时的优点,被业界广泛使用。本文将介绍SpringAMQP与Rabbit的使用,帮助读者更好地理解消息队列。

2.消息队列RabbitMQ使用

2.1 MQ对比

在这里插入图片描述
由上图可知,从可靠性和消息延迟的角度来说,RabbitMQ都是较为突出的,从吞吐量的角度来说可能一般。因此在选用消息队列中间件时,应根据使用场景选择更为合适的。

2.2 AMQP核心概念

名称概念
Server/Broker可以理解为消息队列实体
VHost虚拟主机,一个broker里可以有多个vhost,用作不同用户的权限分离
Exchange消息交换机,它指定消息按一定规则,路由到对应队列
Queue消息队列载体,每个消息可能会被投到一个或多个队列
Producer消息生产者,消息投递方
Consumer消息消费者,接收消息的程序
Binding绑定器,它将exchange和queue按照路由规则绑定起来
channel消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务
Routing Key路由关键字,exchange根据关键字将消息投递到指定queue

2.3 RabbitMQ架构图

在这里插入图片描述

由上图可知,生产者通过channel连接到Broker,将消息投送到Exchange,Exchange再按照指定规则将消息投送到对应的queue,消费者通过监听指定的queue来获取消息。生产者不需要关注投递到那个队列,消费者也不关心消息是从哪个Exchange发送而来,两者之间是松耦合的关系。Exchange的类型有:Fanout交换机、Direct交换机、Topic交换机。Fanout交换机是一种广播模式,消息进来时会投递到所有与之绑定的队列。Direct交换机是完全根据key进行匹配队列,key一致时才会投送。Topic交换机可以按一定的规则进行匹配key,匹配成功进行投递。

2.4 SpringBoot中使用RabbitMQ

2.4.1 引入pom文件

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

2.4.2 添加配置

spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=/
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin

2.4.3 编写生产者

@RunWith(SpringRunner.class)
@SpringBootTest(classes = RabbitApplication.class)
public class SpringAmqpTest {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void testSimpleQueue() {
        // 队列名称
        String queueName = "simple.queue";
        // 消息
        String message = "hello, world!";
        // 发送消息
        rabbitTemplate.convertAndSend(queueName, message);
    }

}

2.4.3 编写消费者

@Component
public class RabbitMQListener {

    @RabbitListener(queues = "simple.queue")
    public void receiveMessage(String message) {
        System.out.println("接收到消息:" + message);
    }
}

2.4.4 测试结果

在这里插入图片描述
运行完成测试代码后,消费者收到消息。上述代码展示的是RabbitMQ最基础的发送和接收模型,生成者将消息发送到指定队列,消费者订阅指定队列获取消息。

2.5 RabbitMQ核心消息发送模型

2.5.1 WorkQueue模型

该模型一个队列可以对应多个消费者,适用于发送者发送大量消息,容易发送积压,因此需要多个消费者来消费。
在这里插入图片描述
2.workQueue测试代码
测试类:

    @Test
    public void testWorkQueue() throws InterruptedException {
        // 队列名称
        String queueName = "work.queue";
        // 消息
        String message = "hello, world";

        for (int i = 1; i <= 50; i++) {
            // 发送消息
            String messageInfo = message + "..." + i;
            rabbitTemplate.convertAndSend(queueName, messageInfo);
            log.info("消息发送成功:{}", messageInfo);
            Thread.sleep(50);
        }
    }

消费代码:

    @RabbitListener(queues = "work.queue")
    public void receiveWorkMessage1(String message) throws InterruptedException {
        System.out.println("消息队列1...接收到消息:" + message);
        Thread.sleep(10);
    }

    @RabbitListener(queues = "work.queue")
    public void receiveWorkMessage2(String message) throws InterruptedException {
        System.out.println("消息队列2...接收到消息:" + message);
        Thread.sleep(15);
    }

3.workQueue运行结果
在这里插入图片描述
在这里插入图片描述

2.5.2 FanoutExchange模型

1.FanoutExchange消息发送模型
在这里插入图片描述
FanoutExchanger模型比简单模型和WorkQueue模型多了一个交换机(Exchange),消息先会发送到Exchange,然后Exchange将消息路由到每一个与其绑定的queue。
2.代码配置

@Configuration
public class FanoutConfig {

    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanout.exchange");
    }

    @Bean
    public Queue fanoutQueue1() {
        return new Queue("fanout.queue1");
    }

    @Bean
    public Binding bindingQueue1(Queue fanoutQueue1, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);
    }

    @Bean
    public Queue fanoutQueue2() {
        return new Queue("fanout.queue2");
    }

    @Bean
    public Binding bindingQueue2(Queue fanoutQueue2, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);
    }

}

发送部分测试代码:

  @Test
    public void testFanout() {
        // 队列名称
        String exchangeName = "fanout.exchange";
        // 消息
        String message = "hello, world!";
        // 发送消息
        rabbitTemplate.convertAndSend(exchangeName,"", message);
    }

3.运行结果
在这里插入图片描述

2.5.3 DirectExchange模型

DirectExchange的消息发送模式与FanoutExchange模型基本一致,区别在于它会将收到的消息根据规则路由到指定的Queue,也就是说中间多了一层根据规则筛选发送队列,它的每一个Queue都与Exchange设置一个BindingKey,发布者发送消息时,指定消息的RoutingKey,Exchange将消息路由到BindingKey与消息RoutingKey一致的队列。
1.代码如下
监听者部分代码如下:

 @RabbitListener(bindings = @QueueBinding(value = @Queue("direct.queue1"),exchange = @Exchange(value = "direct.exchange",type = ExchangeTypes.DIRECT),key = {"red","blue"}))
    public void receiveDirectQueue1(String message) throws InterruptedException {
        System.out.println("消息队列1...接收到消息:" + message);
    }


    @RabbitListener(bindings = @QueueBinding(value = @Queue("direct.queue2"),exchange = @Exchange(value = "direct.exchange",type = ExchangeTypes.DIRECT),key = {"red","yellow"}))
    public void receiveDirectQueue2(String message) throws InterruptedException {
        System.out.println("消息队列2...接收到消息:" + message);
    }

测试代码如下:

 @Test
    public void testDirect() {
        // 队列名称
        String exchangeName = "direct.exchange";
        // 消息
        String message = "hello, world!";
        // 发送消息
        rabbitTemplate.convertAndSend(exchangeName,"red", message);
    }

    @Test
    public void testDirectYellow() {
        // 队列名称
        String exchangeName = "direct.exchange";
        // 消息
        String message = "hello, world!";
        // 发送消息
        rabbitTemplate.convertAndSend(exchangeName,"yellow", message);
    }

2.测试结果
在这里插入图片描述
在这里插入图片描述
由上述结果可知,当队列订阅同一个Exchange时,向指定Exchange并携带RoutingKey,只有包含对应RoutingKey的队列才能收到消息。

2.5.4 TopicExchange模型

TopicExchange与DirectExchange类似,区别在于RoutingKey必须是多个单词的列表,并且以.分割,Queue与Exchange指定BindingKey时可以使用通配符:

#:代指0个或多个单词
*:代指一个单词。

1.测试代码

 @RabbitListener(bindings = @QueueBinding(value = @Queue("topic.queue2"),exchange = @Exchange(value = "topic.exchange",type = ExchangeTypes.TOPIC),key = {"#.news"}))
    public void receiveTopicQueue2(String message) throws InterruptedException {
        System.out.println("消息队列2...接收到消息:" + message);
    }

发送消息部分代码:

@Test
    public void testTopicQueue() {
        // 队列名称
        String exchangeName = "topic.exchange";
        // 消息
        String message = "湖人总冠军";
        // 发送消息
        rabbitTemplate.convertAndSend(exchangeName,"sports.news", message);
    }

2.测试结果
在这里插入图片描述

3.小结

1.RabbitMQ是一个遵循AMQP协议的消息中间件,消息从生产者发送到消费者,他能根据规则指定消息发送对象,缓存或进行持久化;
2.Spring AMQP是基于AMQP协议开放的接口,能够无缝对接各种基于AMQP的协议,快速利用Spring进行开发;
3.RabbitMQ延时低,而可靠性高,适用于吞吐量较大且对信息实时性要求较高的场景。

4.参考文献

1.https://www.bilibili.com/video/BV1LQ4y127n4
2.https://juejin.cn/post/6844903903637536775
3.https://www.cnblogs.com/tinmh/p/6026726.html

5.附录

https://gitee.com/Marinc/nacos.git

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

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

相关文章

路径规划算法:基于多元宇宙算法的路径规划算法- 附代码

路径规划算法&#xff1a;基于多元宇宙优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于多元宇宙优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化…

【Unity Optimize】使用对象池(Object Pooling)优化项目

目录 1 对象池&#xff08;Object Pooling&#xff09;介绍2 实现对象池脚本3 使用对象池生成Cube4 效果展示5 Unity资源商店的对象池插件 1 对象池&#xff08;Object Pooling&#xff09;介绍 Unity中的对象池&#xff08;Object Pooling&#xff09;是一种用于提高游戏性能…

教程详解|如何在PICO眼镜中接入VR全景?

伴随着《万人狂欢泼水节》首场VR直播开启&#xff0c;PICO视频正式推出《跟着PICO去旅行》系列VR文旅直播节目&#xff0c;通过PICO眼镜结合VR技术向众多观众展现更多祖国的大好山河&#xff0c;通过PICO眼镜身临其境地感受云游世界的美妙。 经历了十余年的发展&#xff0c;VR…

esp32环境安装教程---arduino IDE

前言 &#xff08;1&#xff09;最近突然对esp32感兴趣了&#xff0c;源于逛油管的时候&#xff0c;总是看到很多大佬使用esp32cam进行网络图传&#xff0c;做摄像头。个人比较感兴趣&#xff0c;在环境安装过程遇到了很多坑&#xff0c;所以在此跟大家分享一下。 &#xff08;…

了解ChatGPT的最便捷有效方式是跟对人

毕业后&#xff0c;工作原因&#xff0c;我自己的CSND就没有更新过。现在更新一篇有关chatGPT的快速入门指南。 一、什么是chatGPT 2022年12月底&#xff0c;你问我这个问题&#xff0c;我还真得好好跟你解释一下。目前这个阶段的火热程度&#xff0c;这里不再啰嗦了。基于GPT…

AI时代的赚钱思路:23岁女网红如何利用AI技术年入4亿?

一、AI技术为网红赚钱创造新途径 23岁美国网红Caryn Marjorie&#xff08;卡琳玛乔丽&#xff09;正同时交往1000多个男朋友。 作为一个在Snapchat上坐拥180万粉丝的美女&#xff0c;她利用人工智能&#xff08;AI&#xff09;技术&#xff0c;打造了一个AI版本的自己&#x…

鲲鹏昇腾开发者峰会开幕 星辰天合发布新一代天合翔宇一体机

近日&#xff0c;主题为“创未来 享非凡”的鲲鹏昇腾开发者峰会 2023 在东莞松山湖开幕&#xff0c;此次大会旨在帮助开发者深入了解鲲鹏、昇腾全栈技术&#xff0c;加速行业数智化的技术、产品和解决方案创新。 作为鲲鹏生态重要合作伙伴&#xff0c;XSKY星辰天合获邀参加此次…

【利用AI让知识体系化】入门Koa框架

思维导图 文章目录 思维导图一、介绍Koa什么是KoaKoa的历史Koa的特点 二、基本使用安装KoaHello World中间件路由错误处理 三、进阶使用静态资源管理Session管理文件上传表单处理HTTPS支持 四、Koa中间件中间件的概念Koa的洋葱模型常用中间件的介绍自定义中间件的编写 五、异步…

这个水平来面试也敢要20K?还是3年经验的测试工程师....

起因 老板觉得现在公司部门里都是男的&#xff0c;缺少一点阴柔之气&#xff0c;想平衡一下&#xff0c;正巧当时互联网公司倒了一大批&#xff0c;大批简历投到公司&#xff0c;老板以为自己也是技术出身&#xff0c;就想着要招了一个三年工作经验的女测试员&#xff0c;要价…

ANR实战案例1 - Google广告导致ANR解决

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 文章目录 系列文章目录前言一、AdLoader$Builder广告构建ANR二、AdView布局动态创建案例总结 前言 一、AdLoa…

Linux 安装JDK详解

安装步骤 1. 从官网下载安装包保存到 /home/download 下面 2.下载后解压到指定目录&#xff0c;例如&#xff1a;/usr/java/jdk11 3. 解压压缩包 [rootlocalhost linux-x86-64]# cd /usr/java/jdk11 [rootlocalhost jdk11]# [rootlocalhost jdk11]# [rootlocalhost jdk11]…

【换模型更简单】如何用 Serverless 一键部署 Stable Diffusion?

作者&#xff1a;寒斜 本篇章是阿里云函数计算部署 Stable Diffusion 系列的第三篇&#xff0c;如果说第一篇是尝试使用云服务来解决用户本地部署 Stable Diffusion 的问题&#xff08;显卡成本&#xff0c;部署技术复杂&#xff09;&#xff0c;第二篇是面向技术同学解决云服…

Wijmo 2023 v1 Crack

改进了 FlexGrid&#xff0c;支持 React 18 严格模式和可访问性。 5月 15&#xff0c; 2023 - 10&#xff1a;51 新版本 特征 改进了对 React 18 的支持 - 添加了对 React 18 严格模式的支持&#xff0c;可帮助开发人员在开发过程中查找常见错误。辅助功能改进 - 以下是此版本中…

postman工具使用中,遇到的简单疑问

post请求和get请求有什么区别&#xff1f; GET请求和POST请求都是HTTP协议中的两种常见请求方式&#xff0c;主要区别如下&#xff1a; GET请求在请求URL的后面附带参数&#xff0c;而POST请求则将参数包含在请求体中。 GET请求的数据是以查询字符串的形式传递的&#xff0c;而…

JavaEE(系列4) -- 多线程(线程的状态)

目录 观察线程的所有状态 1. new状态 2. TERMINATED 状态 3. RUNNABLE 就绪状态,运行状态 4. TIMED_WAITNG 休眠状态 5. BLOCKED 表示等待锁出现的状态 6. WAITING 使用wait方法出现的状态 观察线程的所有状态 线程的状态是一个枚举类型 public class test2 {public static v…

【AI绘图 丨 Midjourney 系列教程二】— 初识超火的AI绘画神器Midjourney

今天起&#xff0c;由 Midjourney 打头阵&#xff0c;让我们开始共同探索一系列的 AI 领域革命性作品&#xff0c;包括 Midjourney、Stable Diffusion、ChatGPT 等等&#xff0c;学习这些新时代的魔法和它的咒语。 写在前面 官方文档是最好的入门课程。相较于市面上琳琅满目的…

git入门(必看)

git入门 git简介 文章目录 git入门git简介版本控制系统发展可以分为三个阶段&#xff1a; Git 的诞生Git 诞生的背景Linus 两周完成 GitGit 的发展壮大 git安装在 Windows 上安装在 macOS 上安装在 Linux 上安装 Git环境配置配置用户名和邮件地址检查配置Git 颜色配置Git忽略文…

STC15单片机+nRF24L01通讯利用PCA输入捕获触发

STC15单片机+nRF24L01通讯利用PCA输入捕获触发 📍相关篇《STC单片机 NRF24L01通讯实验》📌《STC单片机 NRF24L01通讯带状态反馈》🔖验证对象:STC15L2K60S2📍STC15L2K60S2自制系统板硬件开源地址:https://oshwhub.com/perseverance51/stc15l2k60s2-ji-tong-ban⏱时钟频…

C++ - AVL树

之前的文章中我们学习过二叉搜索树&#xff0c;学习完该部分之后&#xff0c;在进行OJ的练习和思考中会发现如果一颗搜索树由于初始结点选择的不好这棵树就会变成成一颗歪脖子树&#xff0c;这样搜索的效率反而会变的不是很理想。那么在今天的文章中我们就要来介绍一种基于搜索…

【啃书C++Primer5】-c++有些理论基础需要了解,墙裂建议看看原书,有太多细节需要注意了

任何常用的编程语言都具备一组公共的语法特征&#xff0c;不同语言仅在特征的细节上有所区别。要想学习并掌握–种编程语言&#xff0c;理解其语法特征的实现细节是第一步。最基本的特征包括: 整型、字符型等内置类型变量&#xff0c;用来为对象命名 表达式和语句&#xff0c;…