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

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.rhkb.cn/news/316199.html

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

相关文章

场景文本检测识别学习 day07(BERT论文精读)

BERT 在CV领域,可以通过训练一个大的CNN模型作为预训练模型,来帮助其他任务提高各自模型的性能,但是在NLP领域,没有这样的模型,而BERT的提出,解决了这个问题BERT和GPT、ELMO的区别: BERT是用来…

微信小程序:11.本地生活小程序制作

开发工具: 微信开发者工具apifox进行创先Mock 项目初始化 新建小程序项目输入ID选择不使用云开发,js传统模版在project.private.config中setting配置项中配置checkinalidKey:false 梳理项目结构 因为该项目有三个tabbar所以我们要创建三…

springboot拦载器

1、拦载器 package com.Interceptor;import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.security.auth.login.Log…

Linux基本指令(3)

目录 时间相关的指令: 1.在显示方面,使用者可以设定欲显示的格式,格式设定为一个加好后接数个标记,其中常用的标记列表如下: 2.在设定时间方面: 3.时间戳: Cal指令: find指令&a…

部署YUM仓库和NFS共享存储服务

目录 1. YUM仓库服务 1.1 YUM概述 1.2 准备安装源 1.3 yum在线源替换方法 2.制作YUM源 2.1制作ftp源 3.yum软件包的下载方式 4.NFS共享存储服务 4.1 NFS 4.2 NFS网络文件系统 4.3 NFS配置 1. YUM仓库服务 1.1 YUM概述 yum是一个基于RPM包(是Red-Ha…

Java包装类,128陷阱

包装类 基本数据类型都有自己对应的包装类,因为Java本质是面向对象编程的,一切的内容在Java看来都是对象 但是基本数据类型没有类,也没有对象,这样就有了矛盾 所以诞生了基本类型的包装类 基本数据类型: byte,short,…

K8S哲学 - probe 探针

探针分类: liveness probe readiness probe startup probe Liveness Probe:用于检查容器是否还在运行。如果 Liveness Probe 失败,Kubernetes 会杀死容器,然后根据你的重启策略来决定是否重新启动容器。常见的做法是使用与 Readin…

Mysql 、Redis 数据双写一致性 更新策略与应用

零、important point 1. 缓存双写一致性问题 2. java实现逻辑&#xff08;对于 QPS < 1000 可以使用&#xff09; public class UserService {public static final String CACHE_KEY_USER "user:";Resourceprivate UserMapper userMapper;Resourceprivate Re…

如何申请免费SSL证书,把网站升级成HTTPS

HTTPS&#xff08;Hyper Text Transfer Protocol Secure&#xff09;是一种用于安全数据传输的网络协议&#xff0c;它可以有效地保护网站和用户之间的通信安全。然而&#xff0c;要使一个网站从HTTP升级到HTTPS&#xff0c;就需要一个SSL证书。那么&#xff0c;如何申请免费的…

Transformer模型详解01-Word Embedding

文章目录 前言Transformer 整体结构Transformer 的输入单词 Embedding原理CBOW 模型one-hot构建 CBOW 训练数据集构建 CBOW 神经网络训练 CBOW 神经网络 Skip-gram 模型one-hot构建 Skip-gram训练数据集训练 Skip-gram神经网络 Word2Vec实例数据训练保存和加载 前言 Transform…

STM32使用PWM控制舵机

STM32使用PWM控制舵机 1、舵机的控制原理 舵机是一种位置伺服驱动器&#xff0c;是一种带有输出轴的小装置。当我们向伺服器发送一个控制信号时&#xff0c;输出轴就可以转到特定的位置。只要控制信号持续不变&#xff0c;伺服机构就会保持相对的角度位置不变。如果控制信号发…

虹科Pico汽车示波器 | 免拆诊断案例 | 2006 款林肯领航员车发动机怠速抖动

故障现象 一辆2006款林肯领航员车&#xff0c;搭载5.4 L发动机&#xff0c;累计行驶里程约为26万km。该车因发动机怠速抖动故障进厂维修&#xff0c;维修人员更换了火花塞、点火线圈及凸轮轴位置传感器&#xff0c;清洗了积炭和喷油器&#xff0c;故障依旧&#xff0c;于是向笔…

02_c/c++开源库ZeroMQ

1.安装 C库 libzmq sudo apt install libzmq3-dev 实例: https://zeromq.org/get-started/?languagec&librarylibzmq# 编译依赖: pkg-config --cflags --libs libzmq or cat /usr/lib/x86_64-linux-gnu/pkgconfig/libzmq.pc -isystem /usr/include/mit-krb5 -I/usr/in…

Mybatis-Plus学习:快速入门、核心功能、扩展功能、插件功能

文章目录 MybatisPlus快速入门快速开始常见注解常见配置 核心功能条件构造器&#xff08;Wrapper&#xff09;自定义SQLService接口基本用法基础业务接口复杂业务接口Lamda查询Lamda更新批量新增 扩展功能代码生成代码生成器快速开发插件 静态工具逻辑删除枚举处理器JSON处理器…

一例MFC文件夹病毒的分析

概述 这是一个MFC写的文件夹病毒&#xff0c;通过感染USB设备传播&#xff0c;感染后&#xff0c;会向c2(fecure.info:443)请求指令来执行。 样本的基本信息 Verified: Unsigned Link date: 19:52 2007/7/5 MachineType: 32-bit MD5: 4B463901E5858ADA9FED28FC5…

在idea中连接mysql

IDE&#xff08;集成开发环境&#xff09;是一种软件应用程序&#xff0c;它为开发者提供编程语言的开发环境&#xff0c;通常集成了编码、编译、调试和运行程序的多种功能。一个好的IDE可以大幅提高开发效率&#xff0c;尤其是在进行大型项目开发时。IDE通常包括以下几个核心组…

AI系列:大语言模型的RAG(检索增强生成)技术(上)

前言 大型语言模型&#xff08;LLM&#xff09;虽然在生成文本方面表现出色&#xff0c;但仍然存在一些局限性&#xff1a;数据是静态的&#xff0c;而且缺乏垂直细分领域的知识。为了克服这些限制&#xff0c;有时候会进行进一步的模型训练和微调。在实际应用中&#xff0c;我…

leetcode 221 最大正方形面积

示例 3&#xff1a; 输入&#xff1a;matrix [["0"]] 输出&#xff1a;0 # 最大正方形面积 def max_square(matrix):m len(matrix)n len(matrix[0])if m 0 or n 0::return Nonemax_side 1dp [[0] * (n 1) for _ in range(m 1)]for i in range(1, m 1):fo…

Linux进程——进程的概念(PCB的理解)

前言&#xff1a;在了解完冯诺依曼体系结构和操作系统之后&#xff0c;我们进入了Linux的下一篇章Linux进程&#xff0c;但在学习Linux进程之前&#xff0c;一定要阅读理解上一篇内容&#xff0c;理解“先描述&#xff0c;再组织”才能更好的理解进程的含义。 Linux进程学习基…

Unity 数字字符串逗号千分位

使用InputField时处理输入的数字型字符串千分位自动添加逗号&#xff0c;且自动保留两位有效数字 输入&#xff1a;123 输出&#xff1a;123.00 输入&#xff1a;12345 输出&#xff1a;12,345.00 代码非常简单 using UnityEngine; using TMPro;public class …