关于RabbitMQ常见的十道面试题

2024-02-05 15:36

本文主要是介绍关于RabbitMQ常见的十道面试题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

RabbitMQ是如何组成的?它有哪些重要的组件?

RabbitMQ主要由以下几个重要组件组成:

  1. Broker:这是消息代理,主要负责接收、存储和转发消息
  2. Exchanges:交换器,它的主要作用是根据一定的规则匹配消息和队列
  3. Queues:队列,这是存储消息的地方
  4. Bindings:绑定,它是连接交换器和队列的规则
  5. Producers:生产者,它的主要作用是发送消息到交换器

这些组件共同工作,使得RabbitMQ能够提供强大的消息队列功能

RabbitMQ如何保证消息的可靠性的?

RabbitMQ通过以下几种方式来保证消息的可靠性:

  1. 开启事务或者开启confirm模式:这两种方式都可以保证消息不丢失。事务模式会在消息发送过程中加锁,确保消息的可靠性,但是性能较低。而confirm模式则是在消息发送后,Broker会给生产者一个确认应答,告知消息已经正确到达,这种方式性能较高

  2. 开启RabbitMQ持久化:RabbitMQ提供了持久化功能,包括交换机、队列、消息的持久化。这样即使RabbitMQ服务重启,消息也不会丢失

  3. 关闭RabbitMQ自动ack,改成手动确认:这样可以防止消费者在处理消息过程中出现异常导致消息丢失的情况。当消费者收到消息并处理完成后,会给Broker发送一个ack应答,Broker收到应答后才会删除这条消息。如果Broker没有收到应答,那么这条消息会被重新投递给其他消费者

RabbitMQ能保证消息的顺序性吗?怎么保证消息的顺序性?

RabbitMQ可以保证消息的顺序性,主要通过以下方式实现:

  1. 创建多个队列:每个消费者固定消费一个队列的消息,这样就可以保证每个消费者处理的消息是有序的

  2. 生产者发送消息时,同一个订单号的消息发送到同一个队列中:由于同一个队列的消息是一定会保证有序的,那么同一个订单号的消息就只会被一个消费者顺序消费

这样,RabbitMQ就可以保证消息的顺序性了。但需要注意的是,这种方式需要在生产者端进行一定的控制,以确保同一个订单号的消息被发送到同一个队列中。同时,消费者端也需要进行相应的处理,以确保消息的顺序消费

RabbitMQ如何保证幂等性?

RabbitMQ可以通过以下方式来保证幂等性:

  1. 每个消息用一个唯一标识来区分:消费前先判断标识有没有被消费过,若已消费则不再消费

  2. 利用数据库的乐观锁机制:执行更新操作前先去数据库查询version,然后执行更新语句,以version作为条件

  3. 使用Redis的命令:Redis中的set命令天然支持幂等,消息消费时,只需要用set命令来判断消息是否被消费过即可

  4. 全局唯一ID + Redis:生产者在发送消息时,为每条消息设置一个全局唯一的messageId,消费者拿到消息后,使用setnx命令,将messageId作为key放到redis中:setnx (messageId,1),若返回1,说明之前没有消费过,正常消费;若返回0,说明这条消息之前已消费过,抛弃

以上就是RabbitMQ保证幂等性的主要方式。但需要注意的是,这种方式需要在生产者端进行一定的控制,以确保同一个订单号的消息被发送到同一个队列中。同时,消费者端也需要进行相应的处理,以确保消息的顺序消费

说一下RabbitMQ中的死信队列?如何实现死信队列

死信,顾名思义就是无法被消费的消息,字面意思可以这样理解,一般来说,producer将消息投递到broker或者直接到queue里了,consumer从queue取出消息进行消费,但某些时候由于特定的原因导致queue中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信,自然就有了死信队列

消息变成死信有以下几种情况:

  1. 消息被拒绝(basic.reject / basic.nack),并且requeue = false
  2. 消息TTL过期
  3. 队列达到最大长度

死信的处理方式

死信的产生既然不可避免,那么就需要从实际的业务角度和场景出发,对这些死信进行后续的处理,常见的处理方式大致有下面几种:

  1. 丢弃,如果不是很重要,可以选择丢弃
  2. 记录死信入库,然后做后续的业务分析或处理
  3. 通过死信队列,由负责监听死信的应用程序进行处理

综合来看,更常用的做法是第三种,即通过死信队列,将产生的死信通过程序的配置路由到指定的死信队列,然后应用监听死信队列,对接收到的死信做后续的处理。

什么是延迟队列?它的使用场景有哪些?

延迟队列是一种特殊的消息队列,进入该队列的消息会被延迟消费。也就是说,消息一旦入队了之后并不会立即被消费者消费,而是需要等待一段时间后才能被消费。延迟队列的使用场景非常广泛,以下是一些常见的例子

  1. 延迟消费:例如,用户生成订单之后,需要过一段时间校验订单的支付状态,如果订单仍未支付则需要及时地关闭订单
  2. 用户活跃度检查:例如,用户注册成功之后,需要过一段时间比如一周后校验用户的使用情况,如果发现用户活跃度较低,则发送邮件或者短信来提醒用户使用
  3. 延迟重试:例如,消费者从队列里消费消息时失败了,但是想要延迟一段时间后自动重试

以上就是延迟队列的基本概念以及一些常见的使用场景。在实际开发过程中,根据具体的业务需求,延迟队列可以有更多的应用场景

RabbitMQ如何实现延迟队列?

RabbitMQ实现延迟队列主要有两种方式:

  1. 利用RabbitMQ的TTL(Time To Live)特性和死信队列:消息在TTL设置的时间内没有被消费,则会成为“死信”并进入死信队列。具体步骤如下:

    • 声明一个普通队列,比如叫queue_normal
    • 声明一个死信队列,比如叫queue_dead
    • queue_normal设置参数x-dead-letter-exchangex-dead-letter-routing-key,值分别为queue_dead的交换器和路由键
    • queue_normal中的消息变为“死信”时,这些消息会被自动路由到queue_dead
  2. 使用RabbitMQ的插件 rabbitmq_delayed_message_exchange:这是一个官方提供的插件,可以直接用来实现延迟队列。具体步骤如下:

    • 下载并安装rabbitmq_delayed_message_exchange插件
    • 在消息发送时,设置消息的x-delay属性,该属性表示消息延迟的时间
    • 消息会在x-delay设置的时间后被投递到消费者

以上就是RabbitMQ实现延迟队列的主要方式。需要注意的是,这两种方式都需要在生产者端进行一定的控制,以确保消息的延迟投递。同时,消费者端也需要进行相应的处理,以确保消息的顺序消费

RabbitMQ怎么保证高可用的?

RabbitMQ保证高可用主要通过以下几种方式:

  1. 集群部署:RabbitMQ可以通过搭建集群来提高其高可用性。集群中的每个节点都可以处理消息,如果某个节点出现故障,其他节点仍然可以继续处理消息

  2. 镜像队列:RabbitMQ提供了镜像队列的功能,可以将队列的数据同步到多个节点,这样即使某个节点出现故障,其他节点上的镜像队列仍然可以提供服务

  3. 持久化:RabbitMQ提供了持久化机制,可以将交换器、队列、消息进行持久化,这样即使RabbitMQ服务重启,消息也不会丢失

  4. 消息确认机制:RabbitMQ提供了消息确认机制,包括生产者的confirm机制和消费者的ack机制,可以确保消息在网络环境不稳定的情况下也能正确地被发送和接收

  5. 同城双活部署架构:RabbitMQ集群采用同城双活部署架构,依靠MQ-SDK和MQ-NameServer提供的集群寻址、故障快速切换等能力保障集群的可用性

以上就是RabbitMQ保证高可用的主要方式。需要注意的是,这些方式需要在RabbitMQ的配置和使用中进行适当的设置和操作

Kafka为什么运行这么快?

Kafka的高速运行主要归功于以下几种优化方式:

  1. 顺序写入:Kafka中每个分区是一个有序的,不可变的消息序列,新的消息不断追加到partition的末尾,这就是顺序写。顺序写入可以提高磁盘I/O的性能,因为磁盘最喜欢顺序I/O

  2. 零拷贝技术:Kafka在读取的时候使用了零拷贝技术,降低对文件的拷贝次数,一定程度上提升了速度

  3. 大量使用页缓存:Kafka充分利用了操作系统的页缓存来提高I/O效率。页缓存是操作系统对数据文件的读写提供的一种缓冲技术,目的是为了减少I/O操作的次数

  4. 利用Partition实现并行处理:每个Topic都包含一个或多个Partition,不同Partition可位于不同节点,因此可以充分利用集群优势,实现机器间的并行处理

以上就是Kafka能够快速运行的主要原因。需要注意的是,这些优化方式需要在Kafka的配置和使用中进行适当的设置和操作

说一下Kafka的选举流程?

Kafka的选举流程主要是以下几步:

  1. 创建Leader父节点:在Zookeeper中创建一个名为/kafka的持久节点

  2. 各客户端竞争Leader:各客户端在/kafka下创建Leader节点,如/kafka/leader,这个节点被设置为ephemeral_sequential类型,表示这是一个临时的顺序节点

  3. 获取所有子节点并比较:客户端通过getChildren方法获取/kakfa/下所有子节点,然后比较其注册的节点的id和所有子节点中的id,如果其id在所有子节点中最小,则当前客户端竞选Leader成功

  4. 处理Leader故障:如果Leader由于某些原因(如网络故障或者异常退出)与Zookeeper断开连接,那么其他broker通过watch收到控制器变更的通知,就会去尝试创建临时节点/controller,如果有一个Broker创建成功,那么其他broker就会收到创建异常通知,也就意味着集群中已经有了控制器,其他Broker只需创建watch对象即可

  5. 防止控制器脑裂:为了解决Controller脑裂问题,ZooKeeper中还有一个与Controller有关的持久节点/controller_epoch,存放的是一个整形值的epoch number(纪元编号,也称为隔离令牌),集群中每选举一次控制器,就会通过Zookeeper创建一个数值更大的epoch number,如果有broker收到比这个epoch数值小的数据,就会忽略消息

这篇关于关于RabbitMQ常见的十道面试题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/681365

相关文章

RabbitMQ消费端单线程与多线程案例讲解

《RabbitMQ消费端单线程与多线程案例讲解》文章解析RabbitMQ消费端单线程与多线程处理机制,说明concurrency控制消费者数量,max-concurrency控制最大线程数,prefe... 目录 一、基础概念详细解释:举个例子:✅ 单消费者 + 单线程消费❌ 单消费者 + 多线程消费❌ 多

RabbitMQ消息总线方式刷新配置服务全过程

《RabbitMQ消息总线方式刷新配置服务全过程》SpringCloudBus通过消息总线与MQ实现微服务配置统一刷新,结合GitWebhooks自动触发更新,避免手动重启,提升效率与可靠性,适用于配... 目录前言介绍环境准备代码示例测试验证总结前言介绍在微服务架构中,为了更方便的向微服务实例广播消息,

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

Java 方法重载Overload常见误区及注意事项

《Java方法重载Overload常见误区及注意事项》Java方法重载允许同一类中同名方法通过参数类型、数量、顺序差异实现功能扩展,提升代码灵活性,核心条件为参数列表不同,不涉及返回类型、访问修饰符... 目录Java 方法重载(Overload)详解一、方法重载的核心条件二、构成方法重载的具体情况三、不构

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

Python中反转字符串的常见方法小结

《Python中反转字符串的常见方法小结》在Python中,字符串对象没有内置的反转方法,然而,在实际开发中,我们经常会遇到需要反转字符串的场景,比如处理回文字符串、文本加密等,因此,掌握如何在Pyt... 目录python中反转字符串的方法技术背景实现步骤1. 使用切片2. 使用 reversed() 函

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

Python中win32包的安装及常见用途介绍

《Python中win32包的安装及常见用途介绍》在Windows环境下,PythonWin32模块通常随Python安装包一起安装,:本文主要介绍Python中win32包的安装及常见用途的相关... 目录前言主要组件安装方法常见用途1. 操作Windows注册表2. 操作Windows服务3. 窗口操作

ModelMapper基本使用和常见场景示例详解

《ModelMapper基本使用和常见场景示例详解》ModelMapper是Java对象映射库,支持自动映射、自定义规则、集合转换及高级配置(如匹配策略、转换器),可集成SpringBoot,减少样板... 目录1. 添加依赖2. 基本用法示例:简单对象映射3. 自定义映射规则4. 集合映射5. 高级配置匹

在Spring Boot中集成RabbitMQ的实战记录

《在SpringBoot中集成RabbitMQ的实战记录》本文介绍SpringBoot集成RabbitMQ的步骤,涵盖配置连接、消息发送与接收,并对比两种定义Exchange与队列的方式:手动声明(... 目录前言准备工作1. 安装 RabbitMQ2. 消息发送者(Producer)配置1. 创建 Spr