RabbitMQ到底为什么要使用它?

这篇具有很好参考价值的文章主要介绍了RabbitMQ到底为什么要使用它?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

导入

一个技术的衍生必然是为了解决现实出现的问题,在讲这个问题之前我们先了解一下传统开发中关于服务调用出现的问题(痛点)有哪些?


我们为什么要使用MQ?

①、同步——超时

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

在多服务体系架构中,必然存在着多个服务之间的调用关系,当用户提交了订单,订单服务会调用支付服务执行用户的金钱操作,执行完毕之后紧接着调用商品服务对商家的商品信息(库存、成交量、收入等)进行更新,执行完毕之后又调用物流服务(对接发货公司、收发地带你)对用户买的商品进行物流实时同步。每一次的服务调用都要等待另一个服务的执行完,整个流程下来很耗时。对于系统来说要求实时性要强,可立即得到结果,而同步调用还存在着其他问题

资源浪费:调用链中每个服务在等待响应过程中,不能释放请求占用的资源,高并发场景下会极度浪费系统资源

级联失败:如果服务提供者出现问题,所有调用方都会跟着出问题,如同多米诺骨牌一样,迅速导致真个微服务群鼓掌

②、服务耦合高

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

订单服务需要分别调用支付服务、商品服务、物流服务,调用者需要等待服务提供者响应,但是如果作为上游服务的物流服务突然宕机,这样会导致订单服务也会出现问题,用户下单失败;并且如果每次加入新需求,此时如果还需要调用通信服务实时给用户同步下单情况这样一个需求,我们就要修改原来的代码,耦合度很高

③、流量高峰

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

一般在秒杀或团抢活动中使用广泛。比方说订单系统经过测试组接口测试发现最多只能承受100万次请求,而在面对618、双一这种购物狂潮的高峰期,如果一下来了500万的请求系统时是无法处理的,可能会导致数据库无法承受这么大的压力,响应变慢或者直接挂掉

有没有什么办法能够帮助解决上面出现的问题呢?面对上述的种种问题,伟大的人类就提出了一个奇思妙想——把数据暂存。可不可把所有要传输的消息放在一个容器中,当大量请求来的时候先把一部分的消息(逻辑)暂存在容器中,然后慢慢去处理? 于是出现了消息队列的概念


MQ简介

MQ是什么?

Message Queue,消息队列,是基础数据结构中“先进先出”的一种数据结构。把要传输的消息(数据)放在队列中,用队列机制来实现消息传递——生产者生产消息把消息放入队列,然后消费者去处理。消费者可以到指定队列拉取消息,或者订阅响应的队列,由MQ服务端给其推送消息。

为什么要使用队列这种数据结构呢?

我们知道队列具有先进先出的特点。而消息队列就是将消息放到队列里,用队列做存储消息的介质,看作是一个容器。那这里的消息我们可以指代文本字符串,也可以是更复杂的嵌入对象。消息的发送放称为生产者,消息的接收方称为消费者

MQ要解决什么问题?

结合前面讲到应用场景出现的问题,我们来针对性讨论一下方案:

①、同步请求—>异步请求

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

通过引入MQ之后,我为了提升系统响应性能,我们可以它改造为异步,那异步请求有什么好处?它是如何解决同步出现的问题?

异步调用的本质是一种事件驱动模式:

  • 耦合度低(不需要调用对方,只需要发布事件,事件去响应即可)
  • 吞吐量提升(不需要等待对方,执行时间更短,吞吐量更大)
  • 故障隔离(如果出现故障更容易排查)
  • 流量削峰(broker做缓存)

②、高耦合—>低耦合

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

如果使用消息队列,当订单服务执行完成之后,发送一条消息到队列中,其余三个服务读取到这条消息,那么它立刻开始进行业务的执行。使用了消息队列后,消息的发送方和接收方并不需要知道彼此,这样相互之间也就是没有直接关系,即解耦。

③、削峰

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

这种峰值流量场景一般是集中于一小段时间内,为了防止系统在这个峰值时间内被流量冲垮,可以采用消息队列来削弱峰值流量,此时的消息队列就可以理解为是一个缓冲区,比方说系统只能处理100万请求,但此时同时有500万请求来临,我们就可以把把多余的400万请求先放到队列中,等系统根据自己处理请求的能力去消息队列去消费。

一般用来解决应用解耦异步消息,流量削峰等问题,目的是为了实现高性能、高可用、可伸缩和最终一致性架构

MQ的产品有哪些?

RabbitMQ、ActiveMQ、RocketMQ、ZeroMQ、Kafka、IBM WebSphere 等

通过我提出来的应用场景想必大家对于为什么要使用MQ有了初步的了解,接下来我们重点讨论一下RabbitMQ


RabbitMQ

RabbitMQ是什么?

RabbitMQ是一个由Erlang语言开发的AMQP的开源中间件

补充:AMQP是什么?

AMQP我们可以看作是一种协议活规范,而RabbitMQ是基于这个协议下的实现框架。类似于:JDBC和mysql

RabbitMQ的工作原理是什么?

架构图

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

组件

描述

生产者(Producer)

发送消息的应用程序,将消息发送到Broker

消费者(Consumer)

接收消息的应用程序,从RabbitMQ Broker获取消息进行处理

Broker

RabbitMQ消息代理服务器,负责接收和分发消息。

交换机(Exchange)

接收生产者发送的消息,并根据路由键routingKey规则将消息路由到跟交换机绑定的一个或多个队列。

交换机主要用来将生产者生产出来的消息,传送到对应的队列中,即交换机是一个消息传送的媒介(具有存储-转发功能),如果路由不到,或许会返回给 Producer(生产者) ,或许会被直接丢弃掉

绑定(Binding)

定义交换机和队列之间的关系,指定消息的路由规则。

路由键(Routing Key)

生产者在发送消息时,将消息附带的路由键发送给交换机,交换机根据路由键将消息路由到相应的队列。

生产者将消息发给交换器的时候,一般会指定一个 RoutingKey(路由键),用来指定这个消息的路由规则,而这个 RoutingKey 需要与交换器类型和绑定键(BindingKey)联合使用才能最终生效

队列(Queue)

存储消息的容器,消费者从队列中获取消息进行处理。

它是消息的容器,也是消息的终点

整个消息传输流程为:

1. 生产者将消息发送到交换机;

2. 交换机根据路由键将消息路由到相应的队列;

3. 消费者从队列中获取消息进行处理。


RabbitMQ有哪些工作模式?

官方网站:RabbitMQ Tutorials — RabbitMQ

①、Simple(简单工作模式)

特点:一个队列只有一个消费者

消息分发的方式。不同工作模式指的是消息路由的策略和方式不同

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

内部使用的默认交换机

生产者将消息发送到队列,消费者从队列取出消息

②、Work Queues(工作模式)

特点:多个消费者监听同一个队列

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

在一个队列中如果有多个消费者,消费者之间对于同一个消息的关系是竞争关系,同一条消息只能由一个消费者消费。但是分担压力,比方说有10条消息,C1处理13579消息,C2处理246810消息。顺序取消息,C1取一条,C2取一条,消费规则是轮询

应用场景:

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

③、Pub/Sub(订阅模式)

特点:多个消息队列,每个消息队列有一个消费者监听

X:交换机,

生产者生产了消息发给交换机,交换机路由分发给不同的消费者,消费者监听获取消息。一个消息可以被多个消费者同时接收消费

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

每个消费者都监听自己的队列

使用场景:

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

A服务可以通过异常处理,如果A服务发送后出现问题可以回滚,什么都有可能出现问题,而我们的目的是保持一致性

④、Routing(路由模式)

特点:一个交换机绑定多个消息队列,每个消息队列都有自己唯一的key,每个消息队列有一个消费者监听

RabbitMQ到底为什么要使用它?,oracle,网络,数据库

Topics(通配符/主题模式)

*:一个单词

#:零个或多个单词


实战演练

依赖

<dependencies>
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.6.0</version>
        </dependency>
</dependencies>

生产者

package com.itheima.producer;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Producer_HelloWorld {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();

        //2.设置参数
        factory.setHost("114.115.170.214");
        factory.setPort(5672);
        factory.setVirtualHost("/itcast");
        factory.setUsername("admin");
        factory.setPassword("admin");

        //3.创建连接 Connection
        Connection connection = factory.newConnection();

        //4.创建Channel
        Channel channel = connection.createChannel();

        //5.创建队列Queue
        channel.queueDeclare("denglimei",true,false,false,null);

        //要发送的消息
        String body ="hello rabbitmq~~~";

        //6.发送消息
        channel.basicPublish("","denglimei",null,body.getBytes());
         //7.释放资源
        channel.close();
        connection.close();
    }
}

消费者

package com.itheima.consumer;

import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Consumer_HelloWorld {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();

        //2.设置参数
        factory.setHost("114.115.170.214");
        factory.setPort(5672);
        factory.setVirtualHost("/itcast");
        factory.setUsername("admin");
        factory.setPassword("admin");

        //3.创建连接 Connection
        Connection connection = factory.newConnection();

        //4.创建Channel
        Channel channel = connection.createChannel();

        //5.创建队列Queue
        channel.queueDeclare("hello_world",true,false,false,null);

        //匿名内部类
        Consumer consumer = new DefaultConsumer(channel){
            /*
             * 回调方法,当收到消息后,会自动执行该方法
             * 1.consumerTag:标识
             * 2.envelope:获取一些信息,交换机,路由key
             * 3.properties:配置信息
             * 4.body:数据
             * */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
                                       byte[] body) throws IOException {
                long start = System.currentTimeMillis();
                for (int i = 0; i < 10000; i++) {
                    System.out.println("第"+i+"条");
                }
                long end = System.currentTimeMillis();

                System.out.println(start-end);
            }
        };

        //接收消息
        channel.basicConsume("hello_world",true,consumer);

        //注意:消费者作为监听者,不要去关闭资源,否则如何监听资源?
    }
}

总结

本次先对MQ和衍生出来的RabbitMQ先做了基本介绍,后续会针对RabbitMQ如何在项目中如何进行削峰、如何解决死信队列等内容做具体介绍,敬请期待~文章来源地址https://www.toymoban.com/news/detail-594155.html

如果有想要交流的内容欢迎在评论区进行留言,如果这篇文档受到了您的喜欢那就留下你点赞+收藏+评论脚印支持一下博主~

到了这里,关于RabbitMQ到底为什么要使用它?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 报表VS分析:为什么报表做不完?老板到底想要什么?

    各位数据的朋友,大家好,我是老周道数据,和你一起,用常人思维+数据分析,通过数据讲故事。 上一讲和大家讲了分析模型中的战斗机——财务分析模型。通过奥威BI软件的行计算模型来开发财务分析报表异常地简单,前端的组合也非常灵活,财务分析人员就可以搞定。

    2024年02月01日
    浏览(41)
  • 公司为什么选择云数据库?它的魅力到底是什么!

    亚马逊云科技提供了100余种产品免费套餐。其中,计算资源Amazon EC2首年12个月免费,750小时/月;存储资源 Amazon S3 首年12个月免费,5GB标准存储容量;数据库资源 Amazon RDS 首年12个月免费,750小时;Amazon Dynamo DB 25GB存储容量 永久免费。) 谈到数据库想必我们都不陌生,其中主流

    2024年02月04日
    浏览(56)
  • Redis为什么会这么快?Redis到底有多快?

    官方文档:https://redis.io/docs/management/optimization/benchmarks/ 我们使用redis自带的benchmark脚本测试: 我们发现,每秒可以执行11万多次set、lpush命令。 执行Lua脚本也能达到每秒10万多次,按照这个测试结果,redis的10万qps还是比较准确的,在高性能服务器上性能还能更强。 总结起来主

    2024年02月07日
    浏览(51)
  • 一个操作让数组处理速度快了5倍,到底是为什么

      概述: 通过对数组进行排序,代码更好地利用了缓存,从而提高了程序的性能。这种现象通常被称为\\\"缓存友好\\\"(cache-friendly)或\\\"空间局部性\\\"(spatial locality) 今天做一个数组数据计算时,发现一个效率问题,给大家分享一下 一个数组排序和不排序时同样的逻辑处理速度是

    2024年03月24日
    浏览(57)
  • 到底什么是Java AIO?为什么Netty会移除AIO?一文搞懂AIO的本质!

    关于Java网络编程中的同步IO和异步IO的区别及原理的文章非常的多,具体来说主要还是在讨论Java BIO和Java NIO这两者,而关于Java AIO的文章就少之又少了( 即使用也只是介绍了一下概念和代码示例 )。 在深入了解AIO之前,我注意到以下几个现象: 1) 2011年Java 7发布,它增加了

    2024年02月10日
    浏览(39)
  • 神经网络基础-神经网络补充概念-29-为什么使用深层表示

    深层表示(Deep Representation)是指在深度神经网络的多个隐藏层中逐层提取和学习数据的特征表示。 高维特征提取:深层神经网络可以从原始数据中自动学习高维抽象特征。每个隐藏层都对数据进行一些变换,逐步提取更高级别的特征。这有助于发现数据中的复杂模式和结构

    2024年02月12日
    浏览(43)
  • 消息队列选型——为什么选择RabbitMQ

    前言 MQ消息是目前分布式系统必不可少的组件,但是面对市面上众多的MQ组件,我们该用什么呢?我以实际项目的需求出发,介绍今天的主角——rabbitMQ。同时也会告知有哪些优势和不足。事不宜迟,就开始今天的学习吧 目录 一、MQ及MQ组件 1. MQ的解释与用处 2. 几款常用的M

    2024年02月11日
    浏览(50)
  • 神秘的IP地址8.8.8.8地址到底是什么?为什么会被用作DNS服务器地址呢?

    当我们在配置网络连接或者路由器时,经常会遇到需要填写DNS服务器地址的情况。而在这些情况下,很多人都会听到一个神秘的数字地址:8.8.8.8。那么,这个地址到底是什么,为什么会被用作DNS服务器地址呢?本文将详细解释这个问题。 首先,我们需要了解一下什么是DNS。

    2024年02月03日
    浏览(60)
  • 一篇带你肝完Python逆向为什么要学webpack,学完之后到底又该怎么用?

    大家好,我是辣条哥! 之前讲了很多关于基础方面的内容,从本章开始辣条我会开始慢慢开始跟大家解析一些进阶知识以及案例 废话不多说今天我们就深入解析一下webpack,我们先聊一下Python逆向工程为什么还要学习前端的webpack呢? 首先, 学习webpack对于Python逆向工程师来说

    2024年02月12日
    浏览(48)
  • 程序员自学编程的一些误区,你中招了没?自学编程到底为什么重要?给你分享我的5个高效学习方法

    今天又来分享干货了 今天讲一下 就是之前朋友们提的一个问题 就是如何来自学编程 我今天来讲一些 自学编程的话其实最重要的是什么 其实就是一个驱动力 也就是你学习他的目标是什么 很多人没想明白这点就开始去跟着学 最终学的比较痛苦又没有结果 我在高中的时候家里

    2023年04月21日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包