RabbitMQ到底为什么要使用它?

导入

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


我们为什么要使用MQ?

①、同步——超时

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

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

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

②、服务耦合高

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

③、流量高峰

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

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


MQ简介

MQ是什么?

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

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

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

MQ要解决什么问题?

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

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

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

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

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

②、高耦合—>低耦合

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

③、削峰

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

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

MQ的产品有哪些?

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

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


RabbitMQ

RabbitMQ是什么?

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

补充:AMQP是什么?

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

RabbitMQ的工作原理是什么?

架构图

组件

描述

生产者(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(简单工作模式)

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

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

内部使用的默认交换机

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

②、Work Queues(工作模式)

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

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

应用场景:

③、Pub/Sub(订阅模式)

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

X:交换机,

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

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

使用场景:

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

④、Routing(路由模式)

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

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.创建连接 ConnectionConnection connection = factory.newConnection();//4.创建ChannelChannel channel = connection.createChannel();//5.创建队列Queuechannel.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.创建连接 ConnectionConnection connection = factory.newConnection();//4.创建ChannelChannel channel = connection.createChannel();//5.创建队列Queuechannel.queueDeclare("hello_world",true,false,false,null);//匿名内部类Consumer consumer = new DefaultConsumer(channel){/** 回调方法,当收到消息后,会自动执行该方法* 1.consumerTag:标识* 2.envelope:获取一些信息,交换机,路由key* 3.properties:配置信息* 4.body:数据* */@Overridepublic 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如何在项目中如何进行削峰、如何解决死信队列等内容做具体介绍,敬请期待~

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

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

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

相关文章

Kyuubi的介绍优势(官网链接)

官网链接&#xff1a;https://kyuubi.apache.org/ Apache Kyuubi™ 是一个分布式多租户网关&#xff0c;用于在数据仓库和 Lakehouse 上提供无服务器 SQL。 Kyuubi 在各种现代计算框架&#xff08;例如 Apache Spark、 Flink、 Doris、 Hive和Trino等&#xff09;之上构建分布…

全志F1C200S嵌入式驱动开发(GPIO输出)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 和v3s一样,f1c200s本身的外部引脚比较少。所以这个时候,不可避免地,很多引脚的功能就会重叠在一起。这种情况下,我们就要学会取舍了。比如说,如果是学习sd卡的时候,那么spi的…

CSS——基础知识及使用

CSS 是什么 CSS是层叠样式表 (Cascading Style Sheets)的简写.CSS 能够对网页中元素位置的排版进行像素级精确控制, 实现美化页面的效果. 能够做到页面的样式和结构分离。 基本语法规范 选择器 { 一条/N条声明 } 选择器决定针对谁修改 (找谁)声明决定修改啥. (干啥)声明的…

css3的新特性

动画效果 过渡 transition 鼠标放上去瞬间变大 过渡是变大的过程慢慢变化 第一个参数&#xff1a;对哪些值进行过渡。all为hover中所有&#xff0c;也可以指定属性 第二个参数&#xff1a;让动画过渡多长时间。要添加单位&#xff08;s秒&#xff09; 第三个参数&#xff1…

D354周赛复盘:特殊元素平方和+数组最大美丽值(滑动窗口)+合法分割最小下标

文章目录 6889.特殊元素平方和思路完整版取模注意&#xff1a;不能对0取余/取模解答错误&#xff1a;本题的数组最后一个下标是nums[nums.size()] 6929.数组的最大美丽值&#xff08;排序滑动窗口&#xff09;思路1&#xff1a;排序滑动窗口注意点 6927. 合法分割的最小下标&am…

SpringBoot+actuator和admin-UI实现监控中心

使用SpringBoot很久了&#xff0c;但是很少使用到SpringBoot的查看和监控&#xff0c;将来八成也不会用到&#xff0c;万一有机会用到呢&#xff1f;所以记录一下以前学习SpringBootactuator和adminUI实现监控中心的方式 Springboot的版本2.0.x <parent><groupId>…

Spring学习记录---回顾反射机制

目录 10.回顾反射机制 10.1 分析方法四要素 //不使用反射机制调用这些方法 使用反射机制调用方法 代码&#xff1a; 运行结果&#xff1a; 10.4 假设你知道属性名 测试代码 运行结果 10.回顾反射机制 10.1 分析方法四要素 package com.dong.reflect;public class Som…

【java爬虫】将优惠券数据存入数据库排序查询

本文是在之前两篇文章的基础上进行写作的 (1条消息) 【java爬虫】使用selenium爬取优惠券_haohulala的博客-CSDN博客 (1条消息) 【java爬虫】使用selenium获取某宝联盟淘口令_haohulala的博客-CSDN博客 前两篇文章介绍了如何获取优惠券的基础信息&#xff0c;本文将获取到的…

PyTorch 1.13简介

# 1.  PyTorch 1.13 据官方介绍&#xff0c;PyTorch 1.13 中包括了 BetterTransformer 的稳定版&#xff0c;且不再支持 CUDA 10.2 及 11.3&#xff0c;并完成了向 CUDA 11.6 及 11.7 的迁移。此外 Beta 版还增加了对 Apple M1 芯片及 functorch 的支持。 1.1 主要更新 Be…

C++第四讲

思维导图 仿照string类&#xff0c;实现myString类 /* ---------------------------------author&#xff1a;YoungZorncreated on 2023/7/19 19:20.--------------------------------- */ #include<iostream> #include<cstring>using namespace std;class myStri…

【数据结构】时间复杂度---OJ练习题

目录 &#x1f334;时间复杂度练习 &#x1f4cc;面试题--->消失的数字 题目描述 题目链接&#xff1a;面试题 17.04. 消失的数字 &#x1f334;解题思路 &#x1f4cc;思路1&#xff1a; malloc函数用法 &#x1f4cc;思路2&#xff1a; &#x1f4cc;思路3&…

如何使用DiskPart命令行格式化分区?

想要格式化磁盘分区&#xff0c;您可以使用磁盘管理工具&#xff0c;或在Windows文件资源管理器中右键单击驱动器并选择“格式化”。如果您更想使用命令行来格式化磁盘&#xff0c;那么Windows自带的DiskPart将是首选。 DiskPart有很多优点&#xff0c;例如&#xff0c;如果您想…

活动页服务端渲染探索

目标 通过采用在服务端渲染激励页的方式&#xff0c;降低页面加载白屏时间&#xff0c;从而提升激励 H5 渲染体验。 架构设计 前端服务框架调研选型 只对比分析以下两种方案&#xff1a; Vue3 Nuxt3 WebpackNext.js React Node.js ’Nuxt3Next.js介绍Nuxt是一个基于Vu…

Clickhouse基础和基本优化

CK基础和基本优化 一、ClickHouse的特点列式存储高吞吐写入能力数据分区与线程级并行表引擎的使用MergeTreeReplacingMergeTreeSummingMergeTree 二、SQL操作1.Insert2.Update 和 Delete3.查询操作4.alter操作5.导出数据 三、基于表的分布式集群集群写入流程&#xff08; 3分片…

旅游卡加盟代理合伙人模式软件开发

旅游卡加盟代理合伙人模式是近年来逐渐兴起的一种旅游产业发展模式&#xff0c;它通过将旅游卡加盟商与代理商紧密结合&#xff0c;实现资源共享、风险共担、合作共赢的目标。而软件开发作为旅游卡加盟代理合伙人模式的重要技术支持&#xff0c;对于该模式的实施和发展起着至关…

深入理解Java虚拟机(二)Java内存区域与内存溢出异常

一、前言 对于Java程序员来说&#xff0c;在虚拟机自动内存管理机制的帮助下&#xff0c;不再需要为每一个new操作去写配对的delete/free代码&#xff0c;不容易出现内存泄漏和内存溢出问题&#xff0c;看起来由虚拟机管理内存一切都很美好。不过&#xff0c;也正是因为Java程序…

iOS APP外包开发的语言比较

iOS APP是Apple公司运行在iPhone手机上的APP&#xff0c;开发这样的APP有两种开发语言可以选择&#xff0c;都是由Apple公司提供的语言。其中Objective-C使用时间相对较长&#xff0c;有历史兼容考虑&#xff0c;而Swift是新的开发语言&#xff0c;更符合近些年开发语言的发展理…

05 Docker 安装常用软件 (mongoDB)

目录 1. mongoDB简介 1.1 mongodb的优势 2. mongodb的安装 2.1 创建数据文件夹 2.2 备份日志 2.3 配置文件夹 2.4 创建两个文件 ---> 2.4.1 配置如下: 2.5 拉取mongodb 2.6 运行容器 2.7 进入mongodb容器 ---> 2.7.0 高版本(6.0)以上是这样的 , 旧版的没研究 …

服务保护 Sentinel

服务保护 Sentinel Sentinel 介绍Sentinel 的下载使用Sentinel 流控规则流控规则介绍流控规则演示 Sentinel 热点规则Sentinel 隔离和熔断降级Feign 整合 Sentinel线程隔离熔断降级 Sentinel 授权规则Sentinel 系统规则Sentinel 自定义异常Sentinel 资源定义url 默认资源抛出异…

【力扣周赛】第 354 场周赛

文章目录 Q1&#xff1a;6889. 特殊元素平方和思路——简单模拟题竞赛时代码 Q2&#xff1a;6929. 数组的最大美丽值思路——差分数组&#xff0c;计算每个数字可能出现的次数竞赛时代码解法2——排序 双指针⭐解法3——排序 二分查找 Q3&#xff1a;6927. 合法分割的最小下标…