面试题:分布式消息中间件 MQ

news2024/12/24 2:22:36

MQ官网文档:
RabbitMQ:https://www.rabbitmq.com/docs
RocketMQ:https://rocketmq.apache.org/zh/docs/
Kafka:https://kafka.apache.org/documentation/
DDMQ:https://base.xiaojukeji.com/docs/ddmq

面试题:分布式消息中间件 MQ

  • 一、消息队列 MQ
    • 1. 消息队列有哪些应用场景 ?
    • 2. 引入消息队列会带来哪些问题 ?
    • 3. 如何选择合适的消息队列 ?
    • 4. 消息队列有哪些,以及各自的特点 ?
    • 5. 如何避免消息被重复消费 ?
    • 6. 如何保证消息消费的有序性?
    • 7. 如何避免消息堆积 ?
  • 二、RabbitMQ
    • 1.RabbitMQ 如何确保消息不丢失 ?
  • 三、RocketMQ
    • 1. RocketMQ 如何保证高可用性 ?
    • 2. RocketMQ 的存储机制
    • 3. RocketMQ 性能比较高的原因 ?
  • 三、Kafka


一、消息队列 MQ

1. 消息队列有哪些应用场景 ?

  1. 应用解耦提升容错性和可维护性。如下图所示:假设有系统B、C、D都需要系统A的数据,系统A调用三个方法发送数据到B、C、D。这时,系统D不需要了,那就需要在系统A把相关的代码删掉。假设这时有个新的系统E需要数据,这时系统A又要增加调用系统E的代码。为了降低这种强耦合,就可以使用MQ,系统A只需要把数据发送到MQ,其他系统如果需要数据,则从MQ中获取即可。

    在这里插入图片描述

  2. 异步提速提升用户体验和系统吞吐量(单位时间内处理请求的数目)。如下图所示:一个客户端请求发送进来,系统A会调用系统B、C、D三个系统,同步请求的话,响应时间就是系统A、B、C、D的总和,也就是800ms。如果使用MQ,系统A发送数据到MQ,然后就可以返回响应给客户端,不需要再等待系统B、C、D的响应,可以大大地提高性能。对于一些非必要的业务,比如发送短信,发送邮件等等,就可以采用MQ。
    在这里插入图片描述

  3. 削峰填谷提高系统稳定性。如下图所示:这其实是MQ一个很重要的应用。假设系统A在某一段时间请求数暴增,有5000个请求发送过来,系统A这时就会发送5000条SQL进入MySQL进行执行,MySQL对于如此庞大的请求当然处理不过来,MySQL就会崩溃,导致系统瘫痪。如果使用MQ,系统A不再是直接发送SQL到数据库,而是把数据发送到MQ,MQ短时间积压数据是可以接受的,然后由消费者每次拉取1000条进行处理,防止在请求峰值时期大量的请求直接发送到MySQL导致系统崩溃。
    在这里插入图片描述
    使用了 MQ 之后,限制消费消息的速度为1000,这样一来,高峰期产生的数据势必会被积压在 MQ 中,高峰就被“削”掉了,但是因为消息积压,在高峰期过后的一段时间内,消费消息的速度还是会维持在1000,直到消费完积压的消息,这就叫做“填谷”
    在这里插入图片描述

  4. 延时队列:基于RabbitMQ的死信队列或者DelayExchange插件,可以实现消息发送后,延迟接收的效果

  5. 保证数据一致性:解决RPC调用失败从而降级,导致的数据不一致问题。让RPC调用改为MQ异步调用,消息在下游服务故障时堆积起来,等故障恢复后再慢慢处理,减少人工接入的成本

2. 引入消息队列会带来哪些问题 ?

  1. 系统可用性降低
    系统引入的外部依赖越多,系统稳定性越差。一旦 MQ 宕机,就会对业务造成影响。如何保证MQ的高可用?

  2. 系统复杂度提高
    MQ 的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过 MQ 进行异步调用。如何保证消息没有被重复消费?怎么处理消息丢失情况?那么保证消息传递的顺序性?

  3. 一致性问题
    A 系统处理完业务,通过 MQ 给B、C、D三个系统发消息数据,如果 B 系统、C 系统处理成功,D 系统处理失败。如何保证消息数据处理的一致性?

3. 如何选择合适的消息队列 ?

一般而言,不同的MQ解决方案在以下方面可能存在差异:

  • 性能:包括吞吐量延迟并发处理能力等。不同的MQ系统在处理大量消息和高并发请求时,其性能表现可能有所不同。
  • 可靠性:消息队列的可靠性是评估其性能的重要指标之一。这包括消息的持久化消息传递的可靠性故障恢复能力等方面。
  • 功能特性:不同的MQ系统可能提供不同的功能特性,如支持的消息类型消息传递模式消息过滤消息优先级等。
  • 集成与扩展性:MQ系统的集成性扩展性也是重要的考虑因素。系统是否能够轻松集成到现有的技术栈中,以及是否支持水平扩展以满足不断增长的需求,都是需要考虑的问题。

需要根据不同业务需求,与各种消息队列产品的特点,做出选择。

4. 消息队列有哪些,以及各自的特点 ?

MQ(消息队列)是分布式系统中常用的组件,用于实现 异步通信系统解耦流量削峰 等功能。市面上有多种MQ产品,他们各自有特点和适用场景。常见的消息队列中间件包括Kafka、RabbitMQ、ActiveMQ和RocketMQ等。

  1. RabbitMQ
    • 特性:基于Erlang语言开发,支持多种协议(比如AMQP、SMTP)。提供了可靠性持久性分布式易用性等特点(单机12000吞吐量)
    • 优点:功能丰富,性能稳定。社区支持活跃。适合中小型软件公司使用
    • 缺点:在高并发场景下,可能会面临性能挑战
  2. Kafka
    • 特性:基于Scala语言开发。支持自定义协议。是一个分布式高吞吐量的流处理平台,用于构建实时数据管道和流应用程序。(单机100万吞吐量)
    • 优点:可以处理海量数据,具有高吞吐量低延迟特点。适用于大数据和日志收集场景
    • 缺点数据稳定性一般,且无法保障消息有序性。复杂性相对较高,需要一定技术知识与配置。此外,它更偏向于数据流处理,而不是简单的消息队列
  3. RocketMQ
    • 特性:基于Java语言开发,支持自定义协议。是一个高性能高可用的消息队列服务(单机10万吞吐量)
    • 优点:对于消息可靠性有较高要求的场景下是首选。具有强大事务支持消息回溯等功能
    • 缺点:某些方面可能不如RabbitMQ和Kafka功能丰富,且社区支持相对较弱。仅支持Java
  4. ActiveMQ
    • 特性:基于Java语言开发,支持多种协议(比如AMQP、SMTP)。(单机6000吞吐量)
    • 优点:功能全面,稳定性较好,适用于多种场景
    • 缺点:在某些方面可能不如其他MQ产品性能优越,在处理大量消息时可能面临性能挑战。缺乏大规模应用,一般不推荐

在这里插入图片描述

5. 如何避免消息被重复消费 ?

消费者消费消息时采用幂等性方案。
生产者给每一条消息添加唯一ID,消费者根据此ID做幂等性保障

以下展示了采用 分布式锁+持久层数据检查 方案,解决串行、并行的重复请求带来的幂等性问题

在这里插入图片描述

6. 如何保证消息消费的有序性?

其实队列天然具备先进先出的特点,只要消息的发送是有序的,那么理论上接收也是有序的。
不过当一个队列绑定了多个消费者时,可能出现消息轮询投递给消费者的情况,而消费者的处理顺序就无法保证了。

因此,要保证消息的有序性,需要做到以下几点:

  1. 保证消息发送的有序性
  2. 保证一组有序的消息都发送到同一个队列
  3. 保证一个队列只包含一个消费者

7. 如何避免消息堆积 ?

消息堆积问题的产生原因:消息生产速度 > 消息消费速度。

解决方案:

  1. 提高消费者处理速度。优化消费者业务代码,提高性能

  2. 增加更多消费者。一个队列绑定多个消费者,共同争抢消息

  3. 增加消息队列存储上限。RabbitMQ的1.8版本后,引入了新的队列模式:Lazy Queue
    该队列模式不会将消息保存在内存,而是在收到消息后直接写入磁盘,理论上无存储上限


二、RabbitMQ

1.RabbitMQ 如何确保消息不丢失 ?

RabbitMQ针对消息传递过程中可能发生问题的各个地方,给出了针对性的解决方案:

  • 生产者发送消息时可能因为网络问题导致消息没有到达交换机
    • RabbitMQ提供了publisher confirm机制
      • 生产者发送消息后,可以编写ConfirmCallback函数
      • 消息成功到达交换机后,RabbitMQ会调用ConfirmCallback通知消息的发送者,返回ACK
      • 消息如果未到达交换机,RabbitMQ也会调用ConfirmCallback通知消息的发送者,返回NACK
      • 消息超时未发送成功也会抛出异常
  • 消息到达交换机后,如果未能到达队列,也会导致消息丢失
    • RabbitMQ提供了publisher return机制
      • 生产者可以定义ReturnCallback函数
      • 消息到达交换机,未到达队列,RabbitMQ会调用ReturnCallback通知发送者,告知失败原因
  • 消息到达队列后,MQ宕机也可能导致消息丢失
    • RabbitMQ提供了持久化功能集群的主从备份功能
      • 消息持久化,RabbitMQ会将交换机、队列、消息持久化到磁盘,宕机重启可以恢复消息
      • 镜像集群,仲裁队列,都可以提供主从备份功能,主节点宕机,从节点会自动切换为主,数据依然在
  • 消息投递给消费者后,如果消费者处理不当,也可能导致消息丢失
    • SpringAMQP基于RabbitMQ提供了消费者确认机制、消费者重试机制,消费者失败处理策略:
      • 消费者的确认机制:
        • 消费者处理消息成功,未出现异常时,Spring返回ACK给RabbitMQ,消息才被移除
        • 消费者处理消息失败,抛出异常,宕机,Spring返回NACK或者不返回结果,消息不被异常
      • 消费者重试机制:
        • 默认情况下,消费者处理失败时,消息会再次回到MQ队列,然后投递给其它消费者。Spring提供的消费者重试机制,则是在处理失败后不返回NACK,而是直接在消费者本地重试。多次重试都失败后,则按照消费者失败处理策略来处理消息。避免了消息频繁入队带来的额外压力。
      • 消费者失败策略:
        • 当消费者多次本地重试失败时,消息默认会丢弃。
        • Spring提供了Republish策略,在多次重试都失败,耗尽重试次数后,将消息重新投递给指定的异常交换机,并且会携带上异常栈信息,帮助定位问题。

三、RocketMQ

1. RocketMQ 如何保证高可用性 ?

  1. 主从机制

    消息生产的高可用:创建topic时,把topic的多个message queue创建在多个broker组上。这样当一个broker组的master不可用后,producer仍然可以给其他组的master发送消息。

    消息消费的高可用:消费者一般从master上进行消费,当master不可用或者繁忙的时候consumer会被自动切换到从slave读。注意:RocketMQ 是不支持自动主从切换的,当主节点挂掉之后,生产者就不能再给这个主节点生产消息了。

  2. 刷盘机制

    同步刷盘:当数据写如到内存中之后立刻刷盘(同步),在保证刷盘成功的前提下响应client。

    异步刷盘:数据写入内存后,直接响应client。异步将内存中的数据持久化到磁盘上。

RocketMQ采用多住多从,同步复制和异步刷盘保证高可用性。 同步复制: 也叫 “同步双写”,也就是说,只有消息同步双写到主从节点上时才返回写入成功 。
异步复制: 消息写入主节点之后就直接返回写入成功 。

在这里插入图片描述

2. RocketMQ 的存储机制

CommitLog:消息主体以及元数据的存储主体,存储 Producer 端写入的消息主体内容,消息内容不是定长的。单个文件大小默认1G ,文件名长度为20位,左边补零,剩余为起始偏移量,比如00000000000000000000代表了第一个文件,起始偏移量为0,文件大小为1G=1073741824;当第一个文件写满了,第二个文件为00000000001073741824,起始偏移量为1073741824,以此类推。消息主要是顺序写入日志文件,当文件满了,写入下一个文件。

ConsumeQueue:消息消费队列,Consumer 即可根据 ConsumeQueue 来查找待消费的消息。其中,ConsumeQueue作为消费消息的索引,保存了指定 Topic 下的队列消息在 CommitLog 中的起始物理偏移量 offset ,消息大小 size 和消息 Tag 的 HashCode 值。consumequeue 文件可以看成是基于 topic 的 commitlog 索引文件。

IndexFile:IndexFile(索引文件)提供了一种可以通过key或时间区间来查询消息的方法。

在这里插入图片描述

3. RocketMQ 性能比较高的原因 ?

  1. Netty高效的NIO框架
  2. 大量使用多线程异步
  3. 采用零拷贝技术MMAP
  4. 文件存储顺序读写
  5. 锁优化CAS机制无锁化
  6. 存储设计读写分离。

三、Kafka


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

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

相关文章

【LeetCode周赛】第 395 场周赛

目录 3131. 找出与数组相加的整数 I 简单3132. 找出与数组相加的整数 II 中等3133. 数组最后一个元素的最小值 中等3134. 找出唯一性数组的中位数 困难 3131. 找出与数组相加的整数 I 简单 3131. 找出与数组相加的整数 I 分析: 将两个数组中最小的两个值相减即可。…

你的动漫AI女友 Anime gf :自定义创建各种独特个性、语言风格的虚拟角色

一个本地且开源的 CharacterAI 替代工具 Anime gf,提供了一个用户友好的界面,允许用户在桌面上与虚拟角色互动。你可以自定义创建各种角色,让每个虚拟角色都有自己的独特个性和语言风格,可以接入OpenAI、Anthropic、Mistral和 Tog…

Faststone Capture:一触即发的效率革命【AI写作】

首先,这篇文章是基于笔尖AI写作进行文章创作的,喜欢的宝子,也可以去体验下,解放双手,上班直接摸鱼~ 按照惯例,先介绍下这款笔尖AI写作,宝子也可以直接下滑跳过看正文~ 笔尖Ai写作:…

XY_RE复现(二)

一,何须相思煮余年 0x55 0x8b 0xec 0x81 0xec 0xa8 0x0 0x0 0x0 0xa1 0x0 0x40 0x41 0x0 0x33 0xc5 0x89 0x45 0xfc 0x68 0x9c 0x0 0x0 0x0 0x6a 0x0 0x8d 0x85 0x60 0xff 0xff 0xff 0x50 0xe8 0x7a 0xc 0x0 0x0 0x83 0xc4…

【中级软件设计师】上午题12-软件工程(3):项目活动图、软件风险、软件评审、软件项目估算

【中级软件设计师】上午题12-软件工程(3) 1 软件项目估算1.1 COCOMO估算模型1.2 COCOMOⅡ模型 2 进度管理2.1 gantt甘特图2.2 pert图2.3 项目活动图2.3.1 画项目图 3 软件配置管理4 软件风险4.1 风险管理4.2 风险识别4.3 风险预测4.4 风险评估4.5 风险控…

大模型(LLM)调用API论文研究合集

1、API-BLEND: A Comprehensive Corpora for Training and Benchmarking API LLMs 中文标题:API-BLEND: 一个用于训练和评测 API 语言模型的全面语料库 简介:随着大型语言模型(LLM)的发展,它们需要能够有效地利用各种工具和应用程序接口(API)来完成复杂…

GNU Radio之OFDM Channel Estimation底层C++实现

文章目录 前言一、 OFDM Channel Estimation 模块简介二、C 具体实现1、初始化和配置参数2、forecast 函数3、计算载波偏移量4、提取信道响应5、核心的数据处理任务 前言 OFDM Channel Estimation 模块的功能是根据前导码(同步字)估计 OFDM 的信道和粗略…

Java:SpringBoot如何优化启动速度

一、yml中设置懒加载 spring:main:lazy-initialization: true 二、SpringBoot启动类中添加注解 Indexed (Spring5才有该注解) Indexed EnableAsync RestController SpringBootApplication(exclude {WxMaAutoConfiguration.class}) EnableTransactionM…

web服务的部署及高级优化

搭建web服务器 1.1、配置主机IP以及软件仓库搭建 [rootserver129 ~]# vmset.sh 100 //主机IP配置为172.25.254.100 1.2、查看搭建web服务器所需的软件包 [rootserver100 ~]# dnf search nginx 名称 精准匹配:nginx nginx.x86_64 : A high performance web serve…

31.基础乐理-首调与固定调

首调与固定调的概念: 首调 与 固定调 这两个词都是针对 唱名 来说的,针对唱名1234567 来说的,和别的没什么关系,这两个概念是唱名的两种不同表达方式 首调:虽然各个大调实际使用的按键、使用的音名都是不一样的&#x…

【4103】基于小程序实现的老年人健康管理平台

作者主页:Java码库 主营内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】:Java 【框架】:spring…

学习C语言的指针

有一阵没更新了,因为最近比较繁忙,所以更新比较慢,还在慢慢学习 话不多说,开始今天的内容,聊一聊C语言指针。 很多小伙伴可能会被指针这个名字吓到,觉得很难,实际上确实有点难,但是…

算力云平台

先预热下 目标: 算力互联,随需随取;让算力化零为整,化整为零 场景: 1. 个人pc改造,个人算力出租,类似之前的jiluyou模式 2. 服务器中间商准系统集成,目前了解到挖矿不好弄了以后…

MVC架构简述

MVC简介 MVC 是一种非常常见且常用的分层架构,主要包括;M - mode 对象层,封装到 domain 里。V - view 展示层,但因为目前都是前后端分离的项目,几乎不会在后端项目里写 JSP 文件了。C - Controller 控制层&#xff0c…

qt安装历史版本5.15.2

0 背景 因为需要,所以需要安装qt5的最后一个版本qt5.15.2,但是下载qt安装器后,发现没有想要的版本。后面才发现,可以筛选历史版本进行安装。 1 解决 1,打开qt安装程序,勾选Archive后,点击筛选…

【简洁易学】TypeScript 学习笔记

文章目录 TypeScript学习笔记一、TS简介1. 学习前提2. TypeScript是什么?3. TypeScript增加了什么? 二、TS开发环境搭建1. 下载、安装Node.js2. npm安装TypeScript3. 创建一个TS文件,使用tsc对TS文件进行编译 三、TS的类型1. 类型声明2. 类型…

技术不爱听:可视化大屏难点不在于制作过程,而是做成什么样

制作可视化大屏的是一个技术活,需要掌握一定的前端技术和数据可视化技术,例如HTML、CSS、JavaScript、Canvas、SVG、three.js、甚至还涉及到建模、BIM、GIS等等。 但是,仅仅掌握这些技术并不足以制作出一个好的可视化大屏,更重要的…

js逆向进阶篇-某团酒店

提示!本文章仅供学习交流,严禁用于任何商业和非法用途,未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,如有侵权,可联系本文作者删除! 案例分析: 先来看看请求中有哪些参数是需要我们逆向,如下: mtgsig、fp、roh…

数据结构与算法-抽象数据类型ADT系列

以前在学习数据结构的时候做实验,老师要求用ADT抽象数据类型来写这些实现代码。后面也要复习数据结构,在这里就先放下链接。不过以前学习的时候使用的编程语言是C,里面会用到很多指针。现在编代码过程大多数时候都是用Java。不过思路应该还是…

C# WinForm —— 09 标签、文本框、按钮控件

标签 Label 一般显示不能编辑的文本或图像 常用属性、事件: 属性用途(Name)标签对象的ID,在代码里引用标签的时候会用到,一般以 lbl 开头Text设置或获取 界面上显示的 文本信息Image显示图像ImageList图像集,通常和 ListView ToolStrip Tre…