当前位置: 首页 > news >正文

RabbitMQ面试题汇总

RabbitMQ面试题

  • 一、RabbitMQ基础
    • 1. 什么是RabbitMQ,它的基本架构是怎样的?
    • 2. RabbitMQ支持哪些协议?
    • 3. 说一下AMQP协议?
    • 4. 为什么要使用RabbitMQ?
    • 5. MQ的应用场景有哪些?
    • 6. 解耦、异步、削峰是什么?
    • 7. 消息队列有什么缺点?
    • 8. Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?
    • 9. 简单说一下RabbitMQ的缺点?
    • 10. 说说RabbitMQ的工作模式?
    • 11. RabbitMQ消息是怎么路由的?
    • 12. 简单说一下RabbitMQ发送消息的过程。
    • 13. RabbitMQ中的Channel有了解过吗?
  • 二、RabbitMQ高级
    • 1. RabbitMQ中如何保证消息的顺序性?
    • 2. RabbitMQ 如何保证消息不被重复消费?或者说,如何保证消息消费时的幂等性?
    • 3. 如何确保消息正确地发送至 RabbitMQ? 如何确保消息接收方消费了消息?
    • 3. 如何保证RabbitMQ消息的可靠传输?
    • 4. RabbitMQ中如何实现消息的持久化?
    • 5. 如何实现消息的优先级处理?
    • 6. 如何在RabbitMQ中实现优先级队列?
    • 7. RabbitMQ如何处理高并发场景下的性能问题?
    • 8. 如何在RabbitMQ中实现延迟队列?
    • 9. RabbitMQ中的消息什么时候会进入死信交换机?
    • 10. 谈一下对RabbitMQ死信队列的理解?
    • 11. 可以对所有消息都持久化吗?
    • 12. 说一下RabbitMQ事务机制
    • 13. 说说你对RabbitMQ确认机制(应答机制)的理解?
    • 13. 说一下消息确认机制和返回机制,有什么区别?
    • 14. RabbitMQ如何保证高可用?
    • 15. RabbitMQ如何保证高可靠?
    • 16. SpringBoot如何整合RabbitMQ?

一、RabbitMQ基础

1. 什么是RabbitMQ,它的基本架构是怎样的?

RabbitMQ 是一个开源的消息代理和队列服务器,用于通过异步消息传递方式在分布式系统或服务之间进行通信。RabbitMQ 实现了高级消息队列协议(AMQP),同时也支持其他消息协议,如 MQTT 和 STOMP。它由 Erlang 语言编写,因此继承了 Erlang 所具有的高并发、高可用和容错特性。

RabbitMQ 的基本架构包含了以下几个主要组件:

  1. 生产者(Producer):
    生产者是发送消息的应用程序。它创建消息,并可以将消息发送到交换器。

  2. 消费者(Consumer):
    消费者是接收消息的应用程序。它从队列中提取消息并进行处理。

  3. 交换器(Exchange):
    交换器负责接收生产者发送的消息,并根据路由规则将消息路由到一个或多个队列。RabbitMQ 支持几种不同类型的交换器:

    • 直接交换(Direct Exchange)
    • 扇出交换(Fanout Exchange)
    • 主题交换(Topic Exchange)
    • 头交换(Headers Exchange)
  4. 队列(Queue):
    队列是消息最终被消费者接收的地方,它是存放消息的缓冲区。生产者和消费者通常都不直接交互,而是通过队列进行通信。

  5. 绑定(Binding):
    绑定是交换器和队列之间的链接。它告诉交换器消息应该传递到哪些队列。

  6. 虚拟主机(Virtual Host):
    虚拟主机提供了一组独立的环境,每个环境都有自己的交换器、队列和绑定。它们用于逻辑上区分和隔离不同应用程序的消息环境。

  7. 连接(Connection):
    连接是一个 TCP 连接,生产者和消费者通过此连接到 RabbitMQ 服务器。在一个连接内部,可以创建多个通道。

  8. 通道(Channel):
    通道是在连接内部建立的多路传输会话。每个通道代表一个会话任务。

RabbitMQ 服务器(RabbitMQ broker)通常指的是运行RabbitMQ软件的物理服务器或集群。在分布式模式下,RabbitMQ 可以配置为集群模式,以实现负载均衡和高可用性。

RabbitMQ 是一个强大的中间件,它使得应用程序和服务能够通过消息队列以松耦合的形式交换数据,支持多种消息模式,如工作队列、发布订阅、路由和主题消息等。这为跨多个服务和应用程序的可靠消息传递提供了基础设施。

2. RabbitMQ支持哪些协议?

RabbitMQ支持AMQP协议,也支持MQTT、STOMP等其他协议。

3. 说一下AMQP协议?

在这里插入图片描述

4. 为什么要使用RabbitMQ?

  • 在分布式系统下具备异步,削峰,负载均衡等一系列高级功能;

  • 拥有持久化的机制,进程消息,队列中的信息也可以保存下来。

  • 实现消费者和生产者之间的解耦。

  • 对于高并发场景下,利用消息队列可以使得同步访问变为串行访问达到一定量的限流,利于数据库的操作。

  • 可以使用消息队列达到异步下单的效果,排队中,后台进行逻辑下单。

5. MQ的应用场景有哪些?

1. 异步处理

场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种1.串行的方式;2.并行方式。

(1)串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端。
(2)并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间。

假设三个业务节点每个使用50毫秒钟,不考虑网络等其他开销,则串行方式的时间是150毫秒,并行的时间可能是100毫秒。
因为CPU在单位时间内处理的请求数是一定的,假设CPU1秒内吞吐量是100次。则串行方式1秒内CPU可处理的请求量是7次(1000/150)。并行方式处理的请求量是10次(1000/100)。

小结:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢?

引入消息队列,将不是必须的业务逻辑,异步处理。改造后的架构如下:
按照以上约定,用户的响应时间相当于是注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,基本可以忽略,因此用户的响应时间可能是50毫秒。因此架构改变后,系统的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了两倍。

2. 应用解耦

场景说明:用户下单后,订单系统需要通知库存系统。传统的做法是,订单系统调用库存系统的接口。

传统模式的缺点:
1) 假如库存系统无法访问,则订单减库存将失败,从而导致订单失败;
2) 订单系统与库存系统耦合;

如何解决以上问题呢?引入应用消息队列后的方案,如下图:
在这里插入图片描述
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。
库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作。
假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦。

3. 请求削峰

流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛。

应用场景:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。
可以控制活动的人数;
可以缓解短时间内高流量压垮应用;

用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面;
秒杀业务根据消息队列中的请求信息,再做后续处理。

4. 日志处理

日志处理是指将消息队列用在日志处理中,比如Kafka的应用,解决大量日志传输的问题。架构简化如下:
日志采集客户端,负责日志数据采集,定时写受写入Kafka队列;
Kafka消息队列,负责日志数据的接收,存储和转发;
日志处理应用:订阅并消费kafka队列中的日志数据;

(1)Kafka:接收用户日志的消息队列。
(2)Logstash:做日志解析,统一成JSON输出给Elasticsearch。
(3)Elasticsearch:实时日志分析服务的核心技术,一个schemaless,实时的数据存储服务,通过index组织数据,兼具强大的搜索和统计功能。
(4)Kibana:基于Elasticsearch的数据可视化组件,超强的数据可视化能力是众多公司选择ELK stack的重要原因。

5. 消息通讯
消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等。

点对点通讯:
客户端A和客户端B使用同一队列,进行消息通讯。

聊天室通讯:
客户端A,客户端B,客户端N订阅同一主题,进行消息发布和接收。实现类似聊天室效果。

6. 解耦、异步、削峰是什么?

解耦:A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要这个数据呢?那如果 C 系统现在不需要了呢?A 系统负责人几乎崩溃…A 系统跟其它各种乱七八糟的系统严重耦合, A 系统产生一条比较关键的数据,很多系统都需要 A 系统将这个数据发送过来。如果使用 MQ,A系统产生一条数据,发送到 MQ 里面去,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样下来,A 系统压根儿不需要去考虑要给谁发送数据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况。

就是一个系统或者一个模块,调用了多个系统或者模块,互相之间的调用很复杂,维护起来很麻烦。但是其实这个调用是不需要直接同步调用接口的,如果用 MQ 给它异步化解耦。

异步:A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写库,自己本地写库要 3ms,BCD 三个系统分别写库要 300ms、450ms、200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms,接近 1s,用户感觉搞个什么东西,慢死了慢死了。用户通过浏览器发起请求。如果使用 MQ,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms。

削峰:减少高峰时期对服务器压力。

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

  • 系统可用性降低
    本来系统运行好好的,现在你非要加入个消息队列进去,那消息队列挂了,你的系统不是呵呵了。因此,系统可用性会降低;

  • 系统复杂度提高
    加入了消息队列,要多考虑很多方面的问题,比如:一致性问题、如何保证消息不被重复消费、如何保证消息可靠性传输等。因此,需要考虑的东西更多,复杂性增大。

  • 一致性问题
    A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。

所以消息队列实际是一种非常复杂的架构,你引入它有很多好处,但是也得针对它带来的坏处做各种额外的技术方案和架构来规避掉,做好之后,你会发现,妈呀,系统复杂度提升了一个数量级,也许是复杂了 10 倍。但是关键时刻,用还是得用的。

8. Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

在这里插入图片描述

综上,各种对比之后,有如下建议:

  • 一般的业务系统要引入 MQÿ

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【数学建模】介绍论文书写格式
  • YOLOv10实时端到端目标检测
  • 智慧楼宇公厕系统小程序,提高卫生间管理使用效率
  • CDP问卷填报流程-百胜企业管理咨询
  • 8.9 python管理mysql
  • Go语言 Defer(延迟)
  • Flutter-->AAPT: error: resource android:attr/lStar not found.
  • 安卓中Room持久化库的使用
  • 哈希 | Java | (hot100) 力扣 49
  • 重头开始嵌入式第十九天(Linux系统编程 文件IO)
  • Android-->产物收集(含apk文件重命名, aab文件重命名)
  • Mutual_Voting_for_Ranking_3D_Correspondences
  • AFSim 仿真系统----坐标系统
  • 基于CNN的医学X-Ray图像分类全程解析
  • 在Notebook中使用backtrader绘图出现 Javascript Error: IPython is not defined
  • JS 中的深拷贝与浅拷贝
  • crontab执行失败的多种原因
  • ES2017异步函数现已正式可用
  • ESLint简单操作
  • HTML5新特性总结
  • Java|序列化异常StreamCorruptedException的解决方法
  • JavaScript的使用你知道几种?(上)
  • JavaScript对象详解
  • JavaScript学习总结——原型
  • React+TypeScript入门
  • Spark学习笔记之相关记录
  • vue的全局变量和全局拦截请求器
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 力扣(LeetCode)357
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 世界上最简单的无等待算法(getAndIncrement)
  • 我这样减少了26.5M Java内存!
  • 一些关于Rust在2019年的思考
  • gunicorn工作原理
  • Java性能优化之JVM GC(垃圾回收机制)
  • ###项目技术发展史
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • #NOIP 2014# day.1 T2 联合权值
  • #QT(TCP网络编程-服务端)
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • $().each和$.each的区别
  • (0)Nginx 功能特性
  • (1)bark-ml
  • (23)Linux的软硬连接
  • (Ruby)Ubuntu12.04安装Rails环境
  • (ZT)薛涌:谈贫说富
  • (笔试题)分解质因式
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (转载)(官方)UE4--图像编程----着色器开发
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)