RabbitMQ快速上手及讲解

前言:在介绍RabbitMQ之前,我们先来看下面一个场景:

1.1.1.1 异步处理
场景说明:
用户注册后,需要发注册邮件和注册短信,传统的做法有两种

1.串行的方式
(1)串行方式:将注册信息写入数据库后,发送注册邮件,再发送注册短信,以上三个任务全部完成后才返回给客户端。这有一个问题是,邮件,短信并不是必须的,它只是一个通知,而这种做法让客户端等待没有必要等待的东西。
在这里插入图片描述

(2)并行方式:将注册信息写入数据库后,发送邮件的同时,发送短信,以上三个任务完成后,返回给客户端,并行的方式能提高处理的时间。
在这里插入图片描述

假设三个业务节点分别使用50ms,串行方式使用时间150ms,并行使用时间100ms。虽然并性已经提高的处理时间,但是,前面说过邮件和短信对我正常的使用网站没有任何影响,客户端没有必要等着其发送完成才显示注册成功,应该是写入数据库后就返回。
(3)消息队列
引入消息队列后,把发送邮件,短信不是必须的业务逻辑异步处理。
在这里插入图片描述

由此可以看出,引入消息队列后,用户的响应时间就等于写入数据库的时间+写入消息队列的时间(可以忽略不计),引入消息队列后处理后,响应时间是串行的3倍,是并行的2倍。

1.1.2 应用解耦
场景:

双11是购物狂节,用户下单后,订单系统需要通知库存系统,传统的做法就是订单系统调用库存系统的接口。
在这里插入图片描述

这种做法有一个缺点:

  • 当库存系统出现故障时,订单就会失败。
  • 订单系统和库存系统高耦合。

引入消息队列
在这里插入图片描述

订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。

库存系统:订阅下单的消息,获取下单消息,进行库操作。
就算库存系统出现故障,消息队列也能保证消息的可靠投递,不会导致消息丢失。

1.1.3 流量削峰
流量削峰一般在秒杀活动中应用广泛

场景:

秒杀活动,一般会因为流量过大,导致应用挂掉,为了解决这个问题,一般在应用前端加入消息队列。

作用:
1、可以控制活动人数,超过此一定阀值的订单直接丢弃(我为什么秒杀一次都没有成功过呢^^)
2、可以缓解短时间的高流量压垮应用(应用程序按自己的最大处理能力获取订单)

1、用户的请求,服务器收到之后,首先写入消息队列,加入消息队列长度超过最大值,则直接抛弃用户请求或跳转到错误页面。

2、秒杀业务根据消息队列中的请求信息,再做后续处理。

常见MQ产品
ActiveMQ:基于JMS

RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好

RocketMQ:基于JMS,阿里巴巴产品,目前交由Apache基金会

Kafka:分布式消息系统,高吞吐量

一、RabbitMQ快速入门

RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。RabbitMQ官方地址:http://www.rabbitmq.com

二、使用步骤

1.pom.xml里导入相关的依赖:

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

2.application.yml配置文件:

  #rabitMq配置
  rabbitmq:
    host: 120.25.228.68
    port: 5672
    virtual-host: /
    connection-timeout: 10000
    #开启Confirm机制
    publisher-confirm-type: correlated
    #开启Return机制
    publisher-returns: true
    #开启ACK
    listener:
      type: simple
      simple:
        #每次能接收10个消息
        prefetch: 10
        acknowledge-mode: manual
      direct:
        acknowledge-mode: manual

3.rabbitMq交换机讲解:

1、交换机介绍:
先附加下官网文档。RabbitMQ的交换机类型共有四种,是根据其路由过程的不同而划分成的:

2、交换机模式
一、Direct Exchange(直连交换机)
在这里插入图片描述
直连型交换机背后的路由算法很简单——消息会传送给绑定键与消息的路由键完全匹配的那个队列。 我们用直连交换机取代了只会无脑广播的扇形交换机,并且具备了选择性接收消息的能力。

这种配置下,我们可以看到有两个队列Q1、Q2绑定到了直连交换机X上。第一个队列用的是橘色(orange)绑定键,第二个有两个绑定键,其中一个绑定键是黑色(black),另一个绑定键是绿色(green)。在此设置中,发布到交换机的带有橘色(orange)路由键的消息会被路由给队列Q1。带有黑色(black)或绿色(green)路由键的消息会被路由给Q2。其他的消息则会被丢弃。

二、 Fanout Exchange(扇型交换机)

在这里插入图片描述
Fanout Exchange(扇型交换机):当一个Msg发送到扇形交换机X上时,则扇形交换机X会将消息分别发送给所有绑定到X上的消息队列。扇形交换机将消息路由给绑定到自身的所有消息队列,也就是说路由键在扇形交换机里没有作用,故消息队列绑定扇形交换机时,路由键可为空。这个模式类似于广播。

三、Topic Exchange(主题交换机)
在这里插入图片描述
1)路由键和绑定键命名

消息路由键—发送到主题交换机的消息所携带的路由键(routing_key)不能随意命名——它必须是一个用点号分隔的词列表。当中的词可以是任何单词,不过一般都会指定一些跟消息有关的特征作为这些单词。列举几个有效的路由键的例子:“stock.usd.nyse”, “nyse.vmw”, “quick.orange.rabbit”。只要不超过255个字节,词的长度由你来定。
绑定键(binding key)也得使用相同的格式。主题交换机背后的逻辑跟直连交换机比较相似——一条携带特定路由键(routing key)的消息会被投送给所有绑定键(binding key)与之相匹配的队列。尽管如此,仍然有两条与绑定键相关的特殊情况:

  • (星号) 能够替代一个单词。

    #(井号) 能够替代零个或多个单词。

(2)示例解析,如上图:
我们将会发送用来描述动物的多条消息。发送的消息包含带有三个单词(两个点号)的路由键(routing key)。路由键中第一个单词描述速度,第二个单词是颜色,第三个是品种: “<速度>.<颜色>.<品种>”。我们创建三个绑定:Q1通过".orange.“绑定键进行绑定,Q2使用”…rabbit" 和 “lazy.#”。

队列绑定键解释:

Q1针对所有的橘色orange动物。
Q2针对每一个有关兔子rabbits和慵懒lazy的动物的消息。
消息路由键解释:

一个带有"quick.orange.rabbit"路由键的消息会给两个队列都进行投送。消息"lazy.orange.elephant"也会投送给这两个队列。
另外一方面,“quick.orange.fox” 只会给第一个队列。"lazy.pink.rabbit"虽然与两个绑定键都匹配,但只会给第二个队列投送一遍。“quick.brown.fox” 没有匹配到任何绑定,因此会被丢弃掉。
(3)异常情况
如果我们破坏规则,发送的消息只带有一个或者四个单词,例如 “orange” 或者 "quick.orange.male.rabbit"会发生什么呢?结果是这些消息不会匹配到任何绑定,将会被丢弃。另一方面,“lazy.orange.male.rabbit”即使有四个单词,也会与最后一个绑定匹配,并 被投送到第二个队列。

(4)注意事项
主题交换机非常强大,并且可以表现的跟其他交换机相似。

当一个队列使用"#"(井号)绑定键进行绑定。它会表现的像扇形交换机一样,不理会路由键,接收所有消息。
当绑定当中不包含任何一个 “*” (星号) 和 “#” (井号)特殊字符的时候,主题交换机会表现的跟直连交换机一毛一样。

4.在rabbitMq创建好交换机:

这里创建了三种模式的交换机,分为直连模式(direct),广播模式(fanout),主题模式(topic)
在这里插入图片描述

5、队列绑定交换机配置类

/**
 * @author :Mr.ZJW
 * @date :Created 2023/8/30 16:08
 * @description:直连模式交换机配置
 */
@Configuration
public class DirectRabbitConfig {

    /**
     * 队列
     */
    public static final String DIRECT_QUERY = "directQuery";

    /**
     * 交换机
     */
    public static final String DIRECT_EXCHANGE = "directExchange";

    /**
     * 配置队列
     */
    @Bean
    public Queue directQuery() {
        return new Queue(DIRECT_QUERY, true);
    }

    /**
     * 配置交换机
     */
    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange(DIRECT_EXCHANGE);
    }

    /**
     * 绑定交换机
     */
    @Bean
    public Binding bindingPushPassengerInfoToDriverExchange(@Qualifier(DIRECT_QUERY) Queue queue,
                                                            @Qualifier(DIRECT_EXCHANGE) Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DIRECT_QUERY).noargs();
    }

    /**
     * 乱码配置
     */
    @Bean
    public MessageConverter getMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }
}

6、消息生产者配置类:

/**
 * @Author: Mr.ZJW
 * @Date: 2022-07-12 9:30
 * @Description: MQ消息发送
 */
@Configuration
public class MqProduct {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 发送消息 (直连模式)
     *
     * @param msg        消息
     * @param routingKey 消息队列Key
     * @return true or false
     */
    public boolean mqDirectSend(String msg, String routingKey) {
        rabbitTemplate.convertAndSend(DirectRabbitConfig.DIRECT_EXCHANGE, DirectRabbitConfig.DIRECT_QUERY, msg, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                //消息持久化
                message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                return message;
            }
        });
        return true;
    }

}

7、消息消费者配置类:

/**
 * @Author: Mr.ZJW
 * @Date: 2022-07-08 16:29
 * @Description: MQ消费者
 */
@Slf4j
@Component
public class ProductConsumer {

    /**
     * 监听司机信息给乘客
     *
     * @param msg
     * @param message
     * @param channel
     * @throws IOException
     */
    @RabbitListener(queues = "directQuery")
    public void product(String msg, Message message, Channel channel) throws IOException {
        try {
            log.info("receiver success  ProductConsumer:{}", msg);
            log.info("唯一标识:{}", message.getMessageProperties().getCorrelationId());
            //手动ack
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

这里配置类,不完整,可根据自行调整,交换机以及队列可动态配置,配置到配置类等。

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

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

相关文章

ChatGPT⼊门到精通(2):ChatGPT 能为我们做什么

⼀、雇佣免费的⼲活⼩弟 有了ChatGPT后&#xff0c;就好⽐你有了好⼏个帮你免费打⼯的「⼩弟」&#xff0c;他们可以帮你做很多 ⼯作。我简单总结⼀些我⽬前使⽤过的⽐较好的基于ChatGPT的服务和应⽤。 1、总结、分析 当我们在阅读⼀些⽂章和新闻的时候&#xff0c;有的⽂章写…

如何在Spring Boot应用中使用Nacos实现动态更新数据源

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

(第六天)初识Spring框架-SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录

SSM框架的学习与应用(Spring Spring MVC MyBatis)-Java EE企业级应用开发学习记录&#xff08;第六天&#xff09;初识Spring框架 ​ 昨天我们已经把Mybatis框架的基本知识全部学完&#xff0c;内容有Mybatis是一个半自动化的持久层ORM框架&#xff0c;深入学习编写动态SQL&a…

漏洞修复:在应用程序中发现不必要的 Http 响应头

描述 blablabla描述&#xff0c;一般是在返回的响应表头中出现了Server键值对&#xff0c;那我们要做的就是移除它&#xff0c;解决方案中提供了nginx的解决方案 解决方案 第一种解决方案 当前解决方案会隐藏nginx的版本号&#xff0c;但还是会返回nginx字样&#xff0c;如…

重要变更 | Hugging Face Hub 的 Git 操作不再支持使用密码验证

在 Hugging Face&#xff0c;我们一直致力于提升服务安全性&#xff0c;因此&#xff0c;我们将修改 Hugging Face Hub 的 Git 交互认证方式。 从 2023 年 10 月 1 日 开始&#xff0c;我们将不再接受密码作为命令行 Git 操作的认证方式。我们推荐使用更安全的认证方法&#xf…

仿京东 项目笔记2(注册登录)

这里写目录标题 1. 注册页面1.1 注册/登录页面——接口请求1.2 Vue开发中Element UI的样式穿透1.2.1 ::v-deep的使用1.2.2 elementUI Dialog内容区域显示滚动条 1.3 注册页面——步骤条和表单联动 stepsform1.4 注册页面——滑动拼图验证1.5 注册页面——element-ui组件Popover…

【数据库】通过实例讲清楚,Mongodb的增删查改,分组查询,聚合查询aggregate

目录 一.基础概念 二.数据库的管理 1.创建数据库 2.删除数据库 二.集合的管理 1.显示所有集合 2.创建集合 3.删除当前集合 4.向集合中插入元素 三.文档的管理 1.文档插入 2.文档的更新 3.文档的删除 4.文档查询 &#xff08;1&#xff09;查询基本语法&#xff1…

多机单目标跟踪Cross-Drone Transformer Network for Robust Single Object Tracking

1. 摘要 无人机已被广泛用于各种应用&#xff0c;如空中摄影和军事安全&#xff0c;因为与固定摄像机相比&#xff0c;无人机具有高机动性和广阔的视野。多架无人机跟踪系统可以通过收集不同视角的互补视频片段来提供丰富的目标信息&#xff0c;特别是当目标在某些视角下被遮挡…

SPSS统计作图教程:百分条图堆积条图

1、问题与数据 某研究者想看不同年龄分组人群&#xff08;Age_cat&#xff09;中不同程度的维生素D缺乏&#xff08;VD&#xff09;的百分构成比&#xff0c;部分数据如图1。研究者想以条图形式来展现&#xff0c;该如何操作呢&#xff1f; 图1 部分数据 2. 具体操作&#xf…

【小沐学Python】UML类图的箭头连线关系总结(python+graphviz)

文章目录 1、简介1.1 类图1.2 Graphviz 2、Graphviz2.1 安装2.2 命令行测试2.3 python测试 3、关系3.1 实现3.2 泛化3.3 关联3.4 依赖3.5 聚合3.6 组合 结语 1、简介 UML&#xff08;unified modeling language&#xff0c;统一建模语言&#xff09;是一种常用的面向对象设计的…

逻辑回归Logistic

回归 概念 假设现在有一些数据点&#xff0c;我们用一条直线对这些点进行拟合&#xff08;这条直线称为最佳拟合直线&#xff09;&#xff0c;这个拟合的过程就叫做回归。进而可以得到对这些点的拟合直线方程。 最后结果用sigmoid函数输出 因此&#xff0c;为了实现 Logisti…

前端基础4——jQuery

文章目录 一、基本了解1.1 导入jQuery库1.2 基本语法1.3 选择器 二、操作HTML2.1 隐藏和显示元素2.2 获取与设置内容2.3 获取、设置和删除属性2.4 添加元素2.5 删除元素2.6 设置CSS样式 三、jQuery Ajax3.1 基本语法3.2 回调函数3.3 常用HTTP方法3.4 案例一3.4.1 准备工作3.4.2…

PostgreSQL 查询语句大全

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

如何使用『Nginx』配置后端『HTTPS』协议访问

前言 本篇博客主要讲解如何使用 Nginx 部署后端应用接口 SSL 证书&#xff0c;从而实现 HTTPS 协议访问接口&#xff08;本文使用公网 IP 部署&#xff0c;读者可以自行替换为域名&#xff09; 申请证书 须知 请在您的云服务平台申请 SSL 证书&#xff0c;一般来说证书期限…

安卓逆向 - Frida反调试绕过

本文仅供学习交流&#xff0c;只提供关键思路不会给出完整代码&#xff0c;严禁用于非法用途&#xff0c;谢绝转载&#xff0c;若有侵权请联系我删除&#xff01; 本文案例 app&#xff1a;5Lqs5LicYXBwMTEuMy4y 一、引言&#xff1a; Frida是非常优秀的一款 Hook框架&#…

word导出为HTML格式教程,同时也导出图片

在写文档教程时&#xff0c;有时需要借鉴人家的专业文档内容&#xff0c;一般都是word格式文档。word直接复制里面的内容&#xff0c;帐帖到网站编辑器会有很多问题&#xff0c;需要二次清楚下格式才行&#xff0c;而且图片是没办法直接复制到编辑器内的。所以最方便的办法是将…

lv3 嵌入式开发-3 linux shell命令(文件搜索、文件处理、压缩)

目录 1 查看文件相关命令 1.1 常用命令 1.2 硬链接和软链接 2 文件搜索相关命令 2.1 查找文件命令 2.2 查找文件内容命令 2.3 其他相关命令 3 文件处理相关命令 3.1 cut 3.2 sed 过滤 3.3 awk 匹配 4 解压缩相关命令 4.1 解压缩文件的意义 4.2 解压缩相关命令 1 …

在STS里使用Gradle编译Apache POI5.0.0

1、到官方下面地址下载Gradle最新的版本 Gradle Distributions 2、解压后拷贝到D盘下D:\gradle-8.3-rc-4里 3、配置环境变量 新建系统变量 GRADLE_HOME &#xff0c;值为 路径 4、在 Path 中添加上面目录的 bin 文件路径 &#xff08;可以用 %GRADLE_HOME%\bin&#xff0c…

【python爬虫】5.爬虫实操(歌词爬取)

文章目录 前言项目&#xff1a;寻找周杰伦分析过程代码实现重新分析过程什么是NetworkNetwork怎么用什么是XHR&#xff1f;XHR怎么请求&#xff1f;json是什么&#xff1f;json数据如何解析&#xff1f;实操&#xff1a;完成代码实现 一个总结一个复习 前言 这关让我们一起来寻…

React笔记(三)类组件(1)

一、组件的概念 使用组件方式进行编程&#xff0c;可以提高开发效率&#xff0c;提高组件的复用性、提高代码的可维护性和可扩展性 React定义组件的方式有两种 类组件&#xff1a;React16.8版本之前几乎React使用都是类组件 函数组件:React16.8之后&#xff0c;函数式组件使…