Java面试篇【RabbitMQ】常见面试题(2024最新)

RabbitMQ

1.为什么使用MQ?优点是什么

因为MQ可以异步处理,提高系统吞吐量。
应用解耦,系统之间可以通过消息通信,不关心其他系统的处理。
流量削峰,可以通过消息队列的长度,控制请求量。可以缓解短时间内的高并发请求。

解耦:A->BCD,但是如果E也想要这个数据,或者C不想要了。A就需要修改。与各种下游系统严重耦合。
如果使用MQ,A系统产生一条消息,到MQ,哪个系统要消息就去消息系统里去消费。
异步:A接收请求,在本地写库,在BCD三个系统分别要进行写库,本地很快,其它系统完成后传过来很慢,如果同步方式,
A需要BCD都完成之后,才能返回给前端,用户会觉得好慢。如果使用异步化处理的话,A本地写库完成,再往消息队列里写一个数据,就可以返回了。
削峰:大流量来的时候,系统可能承受不住这么大的压力,如果用MQ,就可以对这些请求不用急着处理,转化为MQ里的消息数据,然后以恒定的速率吐出。

2.消息队列有什么缺点?

系统可用性降低:MQ挂了,系统就挂了,增加环节就是在增加风险。
复杂性提高:要考虑的问题多了:比如一致性问题(A的消息给BCD用,BC成功,D失败,就是不一致了),如何保证消息不被重复消费,如何保证消息可靠性传输。

3. 不同的MQ的对比?

  1. ActiveMQ 老牌消息中间件,很多公司运用的很广泛,功能强大,但是互联网公司的高并发扛不住。一般在传统企业,做异步调用,系统解耦。
  2. RocketMQ 阿里开源的,超高并发、高吞吐,性能好,基于java。
  3. rabbitMQ 支持高并发,高吞吐,性能很高,同时有完善的后台管理界面。还支持集群化,高可用部署架构,功能完善。但是缺点是基于erlang开发,不好研究源码。
  4. kafka功能少,优势在于专为超高吞吐量的实时日志采集,实时数据同步,实时数据计算等场景来设计。用在日志或者大数据计算方面比较多。

4.为啥使用rabbitMq不用RocketMQ?

rocketMQ不够稳定,社区活跃度不高,rabbitMQ很稳定。

5.MQ有哪些常见问题?如何解决?

  1. 消息的顺序性问题
  • 单线程化。比如一个订单的各种状态,下单,付款,发货,如果有多个队列,要按照id保证进入一个队列。
  • 一个队列对应一个消费者,这样就能保证顺序。
  • 或者一个队列可以对应多个消费者,但是消费者在业务逻辑内部要做判断,如果订单还在下单阶段就收到了发货的消息,那就只能抛出异常,回复nack,让rabbitMQ重发。
  1. 消息的重复问题
  • 为了确保每条消息至少成功一次的原则,队列里可能一条消息发了多次,需要在业务中做幂等性处理。
    • 查询和删除操作天然幂等。
    • 增改过程需要特殊处理。
  • 举个例子,论坛发帖,在打开编辑页面的时候就产生一个token,服务端存在redis,前端也存一份,然后发送消息的时候,看看redis里有没有这个token,有就新增,同时把redis的token删掉,后面的消息拿着同样的token找不到redis的对应token,就是重复消费,就丢弃。
    在这里插入图片描述
  • 再举个例子,比如一个订单的各种状态,下单,付款,发货,一个字段记录这些状态,1->2->3.
  • 每次的消息就更改状态,消息重复过来了发现状态已经变了,那就不再做任何事情。
  • 订单新增的时候,要在消息里,订单里有唯一的id,可以用uuid,用雪花算法,redis原子自增,等等方式实现。

6. RabbitMQ

一个开源的,erlang编写的,基于AMQP协议的消息中间件

6.1 RabbitMQ的基本概念

在这里插入图片描述

  1. Producer:数据发送方,一般一个消息有两个部分,有效载荷和标签,用标签定位到把消息发送到哪个消费者
  2. Broker: 消息队列服务器实体
  3. Exchange: 消息交换器,从生产者那里收到消息,指定一个routing key,来指定这个消息的路由规则,routing key要和exchange type还有binding key联合使用生效。
  4. binding:绑定,绑定exchange和queue的同时,一般会指定一个binding key。
  5. queue 队列 一个message可以被同时拷贝到多个queue中。
  6. Connection 一个TCP连接,producer和consumer都是通过tcp连接到rabbitMQ server的。
  7. channel是建立在上述的tcp连接中的虚拟连接,AMPQ连接, 如果每一次访问RabbitMQ都建立一个Connection,在消息量大的时候建立TCP Connection的开销将是巨大的,效率也较低。Channel是在connection内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的channel进行通讯,AMQP method包含了channel id帮助客户端和message broker识别channel,所以channel之间是完全隔离的。Channel作为轻量级的Connection极大减少了操作系统建立TCP connection的开销。
  8. Consumer 消费方
  9. virtual host 虚拟主机
  10. 多个不同的用户使用一个rabbitmq server 提供的服务时,可以划分出多个vhost,每个用户在自己的vhost里面建立exchange/queue.
    在这里插入图片描述

6.2 RabbitMQ的工作模式

  1. direct
    消息的routing key与exchange的某个binding key完全符合,则转发到对应的队列中。
  2. fanout
    如果exchange 收到消息,就广播到所有绑定的队列上
  3. topic
    不需要完全匹配,而是符合匹配规则的路由规则即可。#代表任意个单词,*代表一个单词

6.3 ack机制

  1. 有手动和自动ack的方式,一般采用手动。autoAck = false;
  2. 服务端在收到ack信号之后才会删除内存(或者磁盘)中的消息,其实是先标记,再删除。
  3. 队列中有两种消息,一部分是还没有投递出去的消息,一部分已经投递但是还没得到确认的消息。
  4. 如果没有收到确认,消息不会有过期时间,所以也就是给消费者充足的处理时间。只有检测到消费者已经断开了,才会将消息重新放入队列,等待投递给下一个消费者。
  5. 除了ack,还可以拒绝消息,void basicReject(long deliveryTag,boolean requeue);
  6. requeue true重新放入队列,false直接丢弃

6.4 TTL过期时间

  1. 有队列过期时间,还有消息过期时间,以两者较小为准,超过了就过期。
  2. DLX Dead-Letter-Exchange,死信交换机,当一个消息变成死信,就可以发送到另一个交换机,就是死信交换机。
  3. 变成死信三种情况,过期,被拒绝,队列达到最大长度。
  4. 可以用来分析那些被拒绝的消息,转到新的交换机再用新的消费者程序去分析。
    在这里插入图片描述

6.5 延迟队列

  1. 消息放入队列之后,并不会立即被消费,等待一定时间再消费。
  2. 场景:下单之后,十分钟不支付将取消订单,订单信息先发送到正常队列里。然后过了时间之后,再转到另一个交换机–>死信交换机这里再去真正消费。
    在这里插入图片描述

6.6 生产者确认

如何确认消息成功的发送到了rabbitMQ的Exchange?
可以使用事务机制,但是,性能太低了。

try{
    channel.txSelect();
    channel.basicPublish(xxx);
    channel.txCommit();
}catch(Exception e){
    e.printStackTrace();
    channel.txRollBack();
}

在这里插入图片描述
生产者确认

在这里插入图片描述
生产者将channel设置为confirm模式,一旦信道进入comfirm模式,所有在该信道上的消息就会有一个从1开始的编号,deliveryTag,消息到达匹配的队列之后,rabbitMQ会发送Basic.ACK给生产者,包含那个编号,生产者就知道了。
事务机制是阻塞的,生产者确认机制是异步的。生产者收到ACK之后,可以在回调中处理,收到NACK也可以在另一个回调逻辑中处理。

7. 如何保证RabbitMQ消息的可靠传输?

  1. 不可靠一般的原因就是丢了。
  2. 丢失可能是生产者丢失,消息列表丢失、消费者丢失。
  3. 生产者丢失就采用事务或者异步confirm机制,没收到confirm或者收到nack就重发了。这可能导致消息重复。
  4. 消息队列丢失数据:需要消息持久化,配合confirm,持久化磁盘之后再ack,在这之前有问题那么生产者会重发,在这之后有问题,反正已经持久化了有备份。
  5. 消费者丢失,把ack从自动改为手动,处理成功之后ack。造成的消息重复问题,一般需要消费者业务上做幂等性处理。

8.如何保证RabbitMQ的高可用?

为了确保RabbitMQ的高可用性,通常需要考虑以下几个方面:

  1. 集群部署(Clustering)

    将多个RabbitMQ节点配置成集群,可以提供负载均衡和故障转移的能力。在集群模式下,消息队列可以分布在多个节点上,提高系统的吞吐量。如果一个节点失败,其他节点仍然可以继续工作。

  2. 镜像队列(Mirrored Queues)

    在RabbitMQ集群中,可以设置镜像队列来确保队列中的消息被复制到多个节点。如果一个节点崩溃,队列的其他副本可以接管,保证消息不丢失。这是通过设置队列的x-ha-policy参数来实现的。

  3. 持久化(Persistence)

    对消息和队列进行持久化可以保护数据不会因为服务器崩溃而丢失。将消息标记为持久化(通过设置消息的delivery_mode属性为2),并确保队列也被声明为持久化,可以提高数据的可靠性。

  4. 确认和事务机制(Acknowledgments and Transactions)

    使用消息确认机制可以保证消息被正确处理。消费者处理完消息后发送ack(确认)给RabbitMQ,若RabbitMQ没有收到确认,它会将消息重新分发给其他消费者。此外,RabbitMQ还支持事务性消息处理。

  5. 监控和报警(Monitoring and Alerting)

    监控RabbitMQ的运行状况并设置相应的警报机制,可以及时发现并解决潜在的问题。可以利用RabbitMQ提供的管理插件来监视队列的长度、消息吞吐量和节点状态。

  6. 硬件和基础设施的冗余

    在硬件层面,确保服务器、存储和网络连接的冗余可以减少单点故障的风险。使用如RAID或SAN等存储方案可以提高存储系统的可靠性。

  7. 负载均衡(Load Balancing)

    使用负载均衡器可以分散到集群的连接和流量。这不仅增加了系统的吞吐量,也避免了单个节点的过载。

  8. 备份和恢复(Backup and Recovery)

    定期备份RabbitMQ的状态,包括消息队列的配置和消息数据。在发生灾难性故障时,可以用备份快速恢复服务。

  9. 升级和补丁管理

    定期应用RabbitMQ和操作系统的更新和补丁,可以减少因为已知安全问题或软件缺陷导致的服务中断。

  10. 故障切换(Failover)策略

    为系统设计故障切换策略,以便在节点或组件失败时能够快速恢复服务。

要实现这些策略,可能需要对RabbitMQ的高级特性有深入的了解,并且在系统设计和运维阶段做出相应的规划和实施。此外,持续的性能测试和优化也是确保RabbitMQ高可用的重要环节。

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

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

相关文章

Docker的镜像操作

目录 镜像的操作(**开头为常用请留意) 镜像查找 **拉取镜像 **推送镜像 **查看镜像 **修改镜像名称 **查看镜像的详细信息 ​编辑 删除镜像 查看所有镜像ID 删除全部镜像 **查看镜像的操作历史 镜像迁移 镜像打包 远程发送镜像(需要先打包) 本地镜像tar包恢复 镜像过…

【解决方案】腾讯云:对象存储创建存储桶并上传文件后访问对象 url 时文件直接触发下载的问题

大半夜搞服务器后台设置对象存储的时候碰到的问题,看了下文档然后解决了,所以就顺手记录一下。 0x00 问题 & 解决方案 ❓ 问题描述:腾讯云对象存储创建存储桶并上传文件,此时浏览器访问对象 url 时文件时会自动下载该文件&am…

Intel CPU体系结构

原文来自一文解析,Linux内核——Intel CPU体系结构 本文主要介绍Intel CPU体系结构,以供读者能够理解该技术的定义、原理、应用。 🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:计算机杂记…

three.js如何实现简易3D机房?(三)显示信息弹框/标签

接上一篇: three.js如何实现简易3D机房?(二)模型加载的过渡动画:http://t.csdnimg.cn/onbWY 目录 七、创建信息展示弹框 1.整体思路 (1)需求: (2)思路:…

110. 平衡二叉树【简单】

110. 平衡二叉树【简单】 题目描述: 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1 。 示例 1: 输入:r…

Ubuntu 下使用 Pybind11 实现 C++ 调用 Python 接口的示例

Pybind11 是一个轻量级的库,它提供了在 C 中无缝集成 Python 代码的能力。使用 Pybind11,你可以很容易地从 C 调用 Python 代码,反之亦然。下面我将通过一个简单的例子来展示如何在 Ubuntu 系统上使用 Pybind11 从 C 调用 Python 接口。 安装…

Skywalking官方的实战模拟项目Live-Demo

Skywalking 官方的实战模拟项目Live-Demo Live-Demo 是 Skywalking 官方的实战模拟项目,其中包含4个子模块项目 projectA访问projectB、projectC两个SpringBoot项目 projectB访问本地的H2数据库 projectC访问www.baidu.com并同时向一台Kafka消息队列写入数据 proje…

【C语言】冒泡排序

概念 冒泡排序(Bubble Sort)是一种简单的排序算法,它重复地遍历要排序的列表,一次比较两个元素,并且如果它们的顺序错误就把它们交换过来。通过多次的遍历和比较,最大(或最小)的元素…

Bee Mobile组件库重磅升级

Bee Mobile组件库重磅升级! 丰富强大的组件移动预览快速上手create-bee-mobile Bee Mobile组件库重磅升级! Bee Mobile组件库最新 v1.0.0 版本,支持最新的 React v18。 主页:Bee Mobile 丰富强大的组件 一共拥有50多个组件&…

挑战杯 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

Python之Web开发初学者教程—ubuntu下vi的使用

Python之Web开发初学者教程—ubuntu下vi的使用 vi\vim 文本编辑器 i 切换到输入模式,以输入字符。 x 删除当前光标所在处的字符。 : 切换到底线命令模式,以在最底一行输入命令。 vi 保存并退出:esc键退出编辑-…

shell 脚本 if-else判断 和流程控制 (基本语法|基础命令)

CSDN 成就一亿技术人! 作者主页:点击! Shell编程专栏:点击! CSDN 成就一亿技术人 前言———— shell脚本中的if-else功能对于shell程序员来说是一笔重要的财富。当您需要根据预定义条件执行一组语句时&#xff0c…

【数据结构】堆排序

大家好,我是苏貝,本篇博客带大家了解堆排序,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 一. 堆的概念二. 堆排序(以升序为例)三. 代码 一. 堆的概念 如果有一个…

智能便捷|AIRIOT智慧充电桩管理解决方案

现如今随着对可持续交通的需求不断增加,电动车市场正在迅速扩大,建设更多更智能的充电桩,并通过管理平台提高充电设施的可用性和效率成为一项重要任务。传统的充电桩管理平台在对充电设施进行管理过程中,存在如下痛点:…

Spring AOP(二) — 底层组件

Spring AOP 是通过动态代理的方式来实现,主要是通过Pointcut、Advice、Advisor及ProxyFactoryBean 等接口来创建代理对象。 在IoC容器中,Advice 是一个bean(这样可以在通知中使用其他的bean),而Pointcut虽然不是一个B…

【官宣】2024广州国际酒店工程家具及商业空间展览会

2024广州国际酒店工程家具及商业空间展览会 Guangzhou International Hotel Engineering Furniture and commercial space exhibition 2024 时间:2024年12月19-21日 地点:中国进出口商品交易会展馆 承办单位:广州佛兴英耀展览服务有…

同步服务器操作系统公网仓库到本地 _ 统信UOS _ 麒麟KYLINOS

原文链接:同步服务器操作系统公网仓库到本地 | 统信UOS | 麒麟KYLINOS 在如今快速发展的信息技术时代,维护和更新服务器操作系统变得越来越重要。无论是为了提高安全性、增加新功能还是提升系统稳定性,同步公网源仓库到本地都是一个关键步骤。…

Flask入门三(Flask-session的使用、数据库链接池、wtforms、Flask定制命令、Flask-Cache)

文章目录 一、Flask-session使用1.使用方式一2.使用方式二3.读RedisSessionInterface源码4.flask-session补充 二、数据库连接池1.flask中使用mysql2.上述问题解决 使用数据库连接池1.第三方数据库连接池2.操作数据库不带池版3.池版和非池版压测 三、wtforms四、Flask定制命令1…

数据结构部分

来源地址 一 数据结构 1 堆和树之间的区别 区别就在于树是没有特定顺序的,你需要遍历整个树才能找到特定元素;而堆是有序的,你可以直接找到最大(或最小)的元素。 堆:假设你正在开发一个任务调度系统&…

IOS使用Unity容器动态加载3D模型

项目背景 我们的APP是一个数字藏品平台,里面的很多藏品需要展示3D模型,3D模型里面可能会包含场景,动画,交互。而对应3D场景来说,考虑到要同时支持iOS端,安卓端,Unity是个天然的优秀方案。 对于Unity容器来说,需要满足如下的功能: 1.在APP启动时,需要满足动态下载最…