java八股——消息队列MQ

上一篇传送门:点我

目前只学习了RabbitMQ,后续学习了其他MQ后会继续补充。

MQ有了解过吗?说说什么是MQ?

MQ是Message Queue的缩写,也就是消息队列的意思。它是一种应用程序对应用程序的通信方法,使得应用程序能够通过读写出入队列的消息来进行通信,而无需使用专用的连接来链接它们。消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削峰等问题,实现高性能,高可用,可伸缩和最终一致性架构。在消息队列中,有生产者消费者两个角色。生产者负责发送数据到消息队列,而消费者则从消息队列中取出数据进行处理。这种方式实现了生产者与消费者之间的解耦,使得它们可以独立地运行和扩展。

消息队列的优缺点有哪些?

优点:
1.应用解耦:消息队列允许生产者和消费者之间松耦合。生产者只需要将消息发送到队列,而不需要关心消费者何时或如何处理这些消息。
2.异步处理:消息队列允许异步处理消息,这意味着接收者可以在自己方便的时候处理消息,而不是立即响应。这可以提高系统的吞吐量和响应时间。
3.流量削峰:在高并发场景下,消息队列可以起到缓冲作用,平滑突发流量,保护后端系统免受冲击。

缺点:
1.可用性降低:如果消息队列服务成为单点故障,整个系统可能会受到影响。因此,需要实施高可用性和容错策略,一般解决方法是给MQ架集群。
2.复杂性提高:引入消息队列会增加系统的复杂性。因为需要配置和管理消息队列服务,同时还需要处理可能的消息丢失、重复或顺序错乱等问题。
3.一致性问题:在分布式系统中使用消息队列时,如果消息队列发生了消息的丢失与重复,则可能会遇到数据一致性的问题。

说说消息队列的应用场景

消息队列的应用场景主要分为以下三种:
1.异步处理:应用在实时性要求不高的一些场景,例如用户注册发送验证码、下单通知发送优惠券等。这些场景下,服务方只需要把协商好的消息发送到消息队列,剩下的由消费者的消息服务去处理,不需要等待消费者的返回结果就可以直接返回给客户端,返回给业务层面;
2.应用解耦:可以把一些相关的但是耦合度不高的一些系统关联起来,比如订单系统与优惠券积分系统有关联度,但是没有那么紧密,每个系统之间只需要把一些约定好的消息发送到MQ,另外的系统直接去消费就可以了,它可以允许各类系统间采用不同的一些框架和语言来实现,从而大大增加了整个系统的灵活度;
3.流量削峰:应用在大流量入口的一些短时间的业务,短时间内业务需求处理不完的一些服务,例如双十一秒杀、演唱会抢票等。为了权衡高可用把大量的一些并行任务发送给MQ。根据MQ的存储和分发功能平稳的去处理后续的一些业务,从而起到大流量缓冲的作用。

开发过程中有哪些MQ可以选择?如何技术选型?

目前市面上常见的消息队列中间件主要有RabbitMQ、ActiveMQ、RocketMQ、Kafka。这几种消息队列各有优缺点,具体如下:

在这里插入图片描述
由上可以看出,ActiveMQ相较于其它三种消息队列,可用性差,并且吞吐量、消息延迟、可靠性都一般,除了一些小型项目或是追求经济高效的特定需求,ActiveMQ不是消息队列的第一选择,所以现在ActiveMQ不是主流的消息队列了
而由于RabbitMQ是基于Erlang语言开发的,所以如果需要对现有消息队列去做进一步的开发,不推荐使用RabbitMQ(如果只是拿来做简单应用开发就没区别)。
从吞吐量来看,比较好的是RocketMQ和Kafka,其中最好的是Kafka(单机的并发吞吐能力能够达到百万量级),所以如果要追求极致的吞吐能力去处理一些海量数据传输的大数据业务的时候,Kafka会是更好的选择。
而吞吐量高也会带来一定的牺牲,RocketMQ和Kafka的消息延迟(毫秒级)相比RabbitMQ(微秒级)要久很多,如果要追求消息的低延迟就可以选择RabbitMQ。
从可靠性的角度来看,Kafka由于追求极致的并发吞吐量,所以消息可靠性一般,如果要考虑消息的高可靠性,可以选择RabbitMQ或RocketMQ。

说说RabbitMQ的基本架构设计

RabbitMQ的基本架构由以下几个部分组成:
1.生产者(Producer):生产者是消息的发送方,负责产生并发生消息到RabbitMQ。生产者通常将消息发生给交换机(Exchange),从而使其消费者没有强关联。
2.交换机(Exchange):交换机是消息的分发中心,负责将接收到的消息路由到一个或多个消息队列。它定义了消息的传递规则,可以根据规则将消息发送到一个或多个队列中。

  • 直连交换机(Direct Exchange):将消息路由到与消息中的路由键(Routing Key)完全匹配的队列;
  • 主题交换机(Topic Exchange):根据通配符匹配路由键(Routing Key),将消息路由到一个或多个队列;
  • 扇出交换机(Fanout Exchange):将消息广播到所有与交换机绑定的队列,忽略路由键;
  • 头部交换机(Headers Exchange):根据消息头中的属性进行匹配,将消息路由到与消息头匹配的队列。

3.队列(Queue):队列是消息的存储区,用于存储生产者发送的消息。消息最终会被消费者从队列中取出并处理。每个队列都有一个名称,并且可以绑定到一个或多个交换机。
4.消费者(Consumer):消费者是消息的接收方,负责从队列中获取消息并进行处理。消费者通过订阅队列来接收消息。
5.绑定(binding):绑定是交换机和队列之间的关联关系。生产者将消息发送到交换机,而队列通过绑定与交换机相连,从而接收消息。
6.虚拟主机(Virtual Host):虚拟主机是RabbitMQ的基本工作单元,每个虚拟主机都拥有自己独立的用户、权限、交换机、队列等资源,完全隔离于其他虚拟主机。
7.连接(Connection):连接是指生产者、消费者与RabbitMQ之间的网络连接。每个连接都可以包含多个信道(Channel),每个信道是一个独立的会话通道,可以进行独立的消息传递。
8.消息(Message):消息是生产者和消费者之间传递的数据单元。消息通常会包含消息体和可选的属性,如路由键等。

在这里插入图片描述

说说RabbitMQ的交换机类型

1.Direct Exchange(直连交换机)
此类型交换机通过RoutingKey路由键将交换机和队列进行绑定,消息被发送到exchange时,需要根据消息的RoutingKey来进行匹配,只将消息发送到完全匹配此RoutingKey的队列。
2.Fanout Exchange(扇出交换机)
此类型交换机会将消息分发给所有绑定了此交换机的队列,此时RoutingKey无效。在Fanout类型交换机下发送一条消息,无论RoutingKey是什么,所有队列均可收到消息。
3.Topic Exchange(主题交换机)
此类型交换机与Direct类似,也是需要通过RoutingKey路由键进行匹配分发,区别在于Topic可以进行模糊匹配,而Direct是完全匹配。
1.在Topic中,将RoutingKey通过“.”来划分为多个部分;
2.“*”:代表一个部分;
3.“#”:代表0个或多个部分(如果绑定的路由键为“#”时,则接受所有消息,因为路由键所有都匹配)
4.Header Exchange(头部交换机)
Headers Exchange匹配AMQP消息的header而不是路由键,此外headers交换机和direct交换机完全一致,但由于它的性能差,目前几乎用不到了。
在此类交换机中,消费方指定的headers中必须包含一个“x-match”的键。该键的值有两个:
1.x-match = all:表示所有的键值对都匹配才能接收到消息
2.x-match = any:表示只要有键值对匹配就能接受到消息

说说RabbitMQ的持久化机制

RabbitMQ的持久化是一个重要的功能,它确保了即使在RabbitMQ服务器意外关闭或重启的情况下,消息仍然能够得到保存和恢复。RabbitMQ的持久化包括三个方面:交换器的持久化、队列的持久化和消息的持久化
交换器的持久化是通过在声明交换器时指定Durability参数为durable实现的。如果交换器不设置持久化,那么在RabbitMQ服务重启之后,相关的交换器元数据会丢失,但消息不会丢失,只是不能将消息发送到这个交换器中。
队列的持久化也是通过在声明队列时指定Durability参数为durable实现的。如果队列不设置持久化,在RabbitMQ服务重启之后,相关队列的元数据和消息数据都会丢失。设置队列持久化可以确保队列本身的元数据不会因异常情况而丢失,但并不能保证内部所存储的消息不会丢失。为了确保消息不会丢失,需要将消息设置为持久化。
消息的持久化可以通过消息的投递模式来实现。将消息设置为持久化可以确保消息在RabbitMQ服务器意外关闭或重启后能够得到恢复。然而,将所有消息都设置为持久化会严重影响RabbitMQ服务器的性能,因为写入磁盘的速度比写入内存的速度慢得多。因此,在选择是否要将消息持久化时,需要在可靠性和吞吐量之间做一个权衡

如何保证RabbitMQ的消息可靠性传输(保证消息不丢失)?

在RabbitMQ的整个消息投递过程中,有以下三种情况会存在消息丢失的问题:

1.生产者把消息发送到RabbitMQ Server的过程中丢失;
2.RabbitMQ Server收到消息后,在持久化之前宕机导致数据丢失;
3.消费端收到消息后还未来得及处理便宕机,导致RabbitMQ Server认为这个消息已经签收,这个消息就无法重复投递,导致消息无法消费的问题。

所以只需要解决这三个角度的问题,就能保证消息的可靠传输。
从生产者发送消息到Server端的角度来说,RabbitMQ提供了一个Confirm的消息确认机制,也就是说生产者发送的消息到Server端后,如果消息处理成功,Server端会返回客户端一个ack的消息,那么客户端可以根据消息的处理结果来决定是否要对消息进行重新发送,从而确保消息一定要到达到RabbitMQ Server端上;
从Server端的角度来说,可以开启消息的持久化机制,也就是收到消息后,将消息持久化到磁盘里面,设置消息的持久化一般有两个步骤:首先在创建Queue的时候设置为持久化,然后在发送消息的时候,把消息投递模式设置为持久化投递。虽然设置了持久化消息,但是也有可能会出现问题,比如消息刷新到磁盘上之前,RabbitMQ的Server端就发生宕机,这还是会导致消息丢失。为了确保万无一失,需要结合Confirm消息确认机制来一起使用;
从消费者的角度来看,可以把消息的ack机制中的自动确认修改为手动确认(将auto_ack参数设置为false),也就是说消费端只有手动调用消息确认方法,才表示这个消息已经被签收,这种方式可能会造成消息的重复消费,所以还需要考虑到幂等性的设计。

RabbitMQ中如何保证消息不被重复消费?

保证消息不被重复消费,实际上就是解决消息消费端幂等问题 (幂等性,指的是一条指令,任意多次执行所产生的影响均与一次执行的影响相同)。所以只要消费端具备了幂等性,消息重复消费的问题就解决了。
实现消息幂等性可以采用以下两种方案:
1.使用数据库的唯一约束实现幂等,比如对于MQ中的消息,设置一个唯一的消息id,如果消费端多次消费,就会触发数据库的唯一约束异常,从而实现消息的幂等性。
2.使用redis中的setNX指令,在MQ中,为了避免MQ重复消费导致数据被多次修改,消费端可以在接收到消息时,把消息通过setNX写入到redis里面,这样一来一旦消息被消费过,就不会再次被消费。

RabbitMQ中如何解决消息堆积问题?

在RabbitMQ中,出现消息堆积问题的场景一般有以下几种:
1.消息被消费方拒绝,一般来说这种情况是出现在程序或是逻辑有问题的时候。
解决方法:通过添加死信队列或是日志记录的方式避免消息重新入队
2.消费者消费消息的速度慢,从而导致消息的堵塞堆积。
解决方法:通过优化程序代码或建立消费者集群的方式增加消费者的消费能力。
3.队列容量不够,也可能导致消息堆积。
解决方法:增加队列的容量,以容纳更多的待处理消息。

RabbitMQ如何保证消息的顺序消费?

我们说的保证顺序消费,说的是消费者消费信息的顺序。虽然Server端队列中的消息是顺序的,但是由于多个消费者并发消费消息,所以获取消息的速度不一样,从而可能会导致消息的消费顺序出现问题。
想要解决顺序消费的问题,通常的解决办法就是一个队列只有一个消费者,这样就可以一个个消息按顺序处理,但缺点就是并发能力下降,无法并发消费消息,这是个取舍的问题。
也可以在发送消息时使用一些标识符或分区键将消息分区,并确保具有相同标识符的消息被发送到同一个队列。然后,可以使用多个消费者,每个消费者处理一个特定的分区,从而保证了消息在特定分区内的顺序性。

RabbitMQ如何给消息设置过期时间?

在RabbitMQ中存在2种方法设置消息的过期时间。第一种方法是通过对队列进行设置,这种设置后,该队列中所有的消息都存在相同的过期时间;第二种方法是通过对消息本身进行设置,那么每条消息的过期时间都不一样。如果同时使用这两种方法,那么以过期时间较小的哪个数值为准。当消息达到过期时间还没有被消费,那么该消息就成为了一个死信消息
队列设置:在队列中声明的时候使用x-message-ttl参数,单位为 毫秒。
单个消息设置:设置消息属性的expiration参数的值,单位为 毫秒。

说说RabbitMQ的死信队列

当队列中的消息被拒绝、或者消息过期会变成死信,死信可以被重新发布到另一个交换机,这个交换机是死信交换机(DLX,Dead Letter Exchange),与DLX绑定的队列被称为死信队列
出现死信的原因一般有以下几点:1.消息被消费方拒绝(消费方使用channel.basicNack或channel.basicReject,并且此时requeue属性被设置为false);2.消息超出过期时间超时;3.消息总量超过了队列的最大长度

说说RabbitMQ的延迟队列

延迟队列存储的是延迟消息。延迟消息是指,当消息被发布出去后,并不立即投递给消费者,而是在指定时间之后投递。例如:在订单系统中,订单有30秒的付款时间,在订单超时之后再投递给消费者处理超时订单。
RabbitMQ没有直接支持延迟队列,可以通过死信队列来实现。在死信队列中,可以为普通交换机绑定多个消息队列,假设绑定过期时间为5分钟,10分钟和30分钟三个消息队列,然后为每个消息队列设置DLX,为每个DLX关联一个死信队列。
当消息过期后,消息会被转存到对应的死信队列中,然后投递给指定的消费者消费。

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

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

相关文章

AI大模型专题:2024大模型赋能下的AI 2.0数字人平台白皮书

今天分享的是AI大模型专题系列深度研究报告:《AI大模型专题:2024大模型赋能下的AI 2.0数字人平台白皮书》。 (报告出品方:商汤) 关键发现 生成式 AI 和大模型技术的飞速发展正推动 AI数字人向更高级别进化&#xff…

JavaScript_语法--变量

1.4 变量 变量:一小块存储数据的内存空间 Java语言是强类型语言,而JavaScript是弱类型的语言 强类型: 在开辟变量存储空间时,定义了空间将来存储的数据的数据类型。只能存储固定类型的数据 弱类型: 在开辟变量存储空间…

GeoServer:忘记密码重置

操作步骤 1. 找到data_dir/security/usergroup/default目录下的users.xml文件, 2.修改password为plain:geoserver, 这里无论原来的密码是什么,改为plain:geoserver之后,就可以通过admin:geoserver默认账户密码登录了。…

3d模型有边界框怎么去除---模大狮模型网

在3D建模软件中,边界框通常是用来表示模型的边界和外轮廓的,但有时候在渲染或导出模型时可能不希望显示这些边界框。以下是一些去除3D模型边界框的方法: 隐藏边界框选项: 在大多数3D建模软件中,边界框的显示可以通过简…

【电子通识】普通电阻、敏感电阻、可调电阻的种类和特点

电阻的作用 在【分立元件】理解电阻 中我们知道电阻是在电路中对电流产生阻碍作用的元件。电阻是电子产品中最基本、最常用的电子元件之一。 有各产品的电路板中基本都有电阻器,通常起限流、滤波或分压等作用。实际上,电阻器的种类很多,根据其…

解决Idea中文乱码

解决 Idea 中文乱码问题的方法通常包括以下几个步骤: 1、调整文件编码:确保项目中的文件编码与 Idea 中的编码设置一致。通常情况下,使用 UTF-8 编码是比较合适的选择。你可以在 Idea 中通过 File -> Settings -> Editor -> File E…

高阶流程图(SIPOC)

SIPOC高阶流程图是一种流程映射和改进方法,它使用可视化的方式描述一个或多个流程的输入和输出。SIPOC是五个单词的首字母缩写,分别代表供应商(Suppliers)、输入(Inputs)、过程(Processes&#…

Blazor OIDC 单点登录授权实例7 - Blazor hybird app 端授权

目录: OpenID 与 OAuth2 基础知识Blazor wasm Google 登录Blazor wasm Gitee 码云登录Blazor OIDC 单点登录授权实例1-建立和配置IDS身份验证服务Blazor OIDC 单点登录授权实例2-登录信息组件wasmBlazor OIDC 单点登录授权实例3-服务端管理组件Blazor OIDC 单点登录授权实例4 …

Hadoop安装部署-NameNode高可用版

Hadoop分布式文件系统支持NameNode的高可用性,本文主要描述NameNode多节点高可用性的安装部署。 如上所示,Hadoop分布式文件系统部署了NameNode的Master主节点以及NameNode的Slave副节点,当Master主节点发生故障变得不可用时,ZooK…

建筑业AI的崛起

建筑领域完全可以从机器学习和人工智能(AI)的出现中受益。 本文总结了这一领域的发展,并介绍了人们可以准备从这项技术中实现价值最大化的一些方法,包括对人工智能和机器学习在建筑中的一些应用及其潜在影响的广泛调查。 这些流程…

基于springboot的医院药品管理系统

前言 基于Java的医院药品管理系统是一个利用JAVA技术建设的网上管理系统,在基于Java的医院药品管理管理中实现信息化。系统的设计就是为了迎合广大用户需求而创建的一个界面简洁、有定向内容、业务逻辑简单易操作的基于Java的医院药品管理系统。本文以基于Java的医…

【论文解读】大模型事实性调查(下)

http://t.csdnimg.cn/4md5U 上期我们分享了《大模型事实性调查》论文解读的前半部分,这一期为大家带来后面的内容,欢迎阅读交流。 四、事实性分析 在前面的第3节中,论文提供了与评估事实性相关的定量统计数据。在本节中,论文将更…

2024年第15届蓝桥杯嵌入式组注意事项之新建LCD工程

2024年第15届蓝桥杯嵌入式组注意事项之新建LCD工程 今天是2024年4月11日,距离蓝桥杯比赛还有一天开始,几日前本人拿到了今年赛场的资源包,发现了一点的变化 首先是文件夹的结构往年有所不同 最重要的变化还是LCD的例程的变化,往年…

记录vite打包并上传到npm

开始 起因:我们单位这个项目用的vitereact使用print打印 开发环境没问题、一到打包时就卡住、所以我就想单独打包成组件在引用看看还有问题么、结果还真可以!又是离谱的一天 首先需要把npm的分支切换成官网地址、因为只有官网地址才能登陆npm账号 这里说…

Mac上的最佳3D建模工具-犀牛Rhinoceros 8 for Mac v8.6.24101.05002完美兼容激活

Rhino 8是一款计算机辅助设计(CAD)和三维建模软件,由美国公司McNeel & Associates开发。它是Rhino系列的最新版本,用于创建、编辑、分析、渲染和动画三维模型。 以下是Rhino 8的一些主要特点和功能: 1. **强大的…

五、书架开发--1.书架标题组件交互、获取书架数据

添加书架页面,做路由配置 首先添加书架页面,到views中的store中添加一个StoreShelf表示书架 然后到路由中进行注册 然后书城首页的返回键我们是想要点击返回的话就跳转到书架页面,所以如下this.$router.push(/store/shelf) 做书架标题组件 …

Nevion视频会议光端机AAV-3G-XMUX系列

序号型号描述(厂商:Nevion)3G/HD/SD-SDI 视音频光端机,0-20km1AAV-3G-XMUX-SFP3G/HD/SD-SDI 音频嵌入/解嵌器模块,带SFP光模块插座。支持4路AES加嵌和解嵌,8路模拟音频加嵌。内置音频矩阵及处理器模块&…

【spring】@Profile注解学习

Profile介绍 在Spring框架中,Profile注解用于根据特定的配置文件来有条件地激活或禁用Bean的定义。这在开发和测试过程中非常有用,因为它允许你为不同的环境(如开发、测试、生产)定义不同的配置。 Profile不仅可以标注在方法上&…

PCB封装库的创建及引入

法1 1.创建lib 2.放置 找到你想要画的封装的器件的数据手册了解相关信息。 直插式选Multi-layer 贴片选Top-layer 焊盘尺寸 焊盘空尺寸 法2 嘉立创eda直接copy 再嘉立创中找到你想要的pcb,导出为ad 然后再ad中找到我们导出的文件 复制他 然后再库中粘贴 pcb库…

【算法】哈希表

个人主页 : zxctscl 如有转载请先通知 题目 1. 1. 两数之和1.1 分析1.2 代码 2. 面试题 01.02. 判定是否互为字符重排2.1 分析2.2 代码 3. 217. 存在重复元素3.1 分析3.2 代码 4. 219. 存在重复元素 II4.1 分析4.2 代码 5. 49. 字母异位词分组5.1 分析5.2 代码 1. 1…