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

一小时解决RabbitMQ面试题

消息队列的定义

消息队列(Message Queue)是一种异步通信机制,用于在分布式系统或应用程序组件之间传递数据。发送者(生产者)将消息放入队列,接收者(消费者)按顺序或优先级从队列中获取并处理消息。队列作为中间件,解耦生产者和消费者,确保消息的可靠传递。

消息队列的核心作用

他的作用主要是:解耦,异步,削峰填谷(下面是解释,帮助大家理解)

解耦系统组件
生产者和消费者无需直接交互,通过队列间接通信。系统组件可以独立扩展、修改或替换,降低耦合度。例如,订单系统生成订单消息后,物流系统无需实时在线即可后续处理。

异步处理
生产者发送消息后无需等待消费者处理完成,提高系统响应速度。适合处理耗时任务(如日志记录、邮件发送),避免阻塞主业务流程。

流量削峰
在高并发场景下,队列作为缓冲区平滑突发流量,避免消费者过载。例如电商秒杀活动,请求先进入队列,系统按处理能力消费。

数据持久化与可靠性
多数消息队列支持消息持久化,确保系统崩溃或网络故障时数据不丢失。支持重试机制和死信队列处理失败消息。

顺序性与负载均衡
队列可保证消息的顺序性(如Kafka分区)。多个消费者可并行处理同一队列的消息,实现负载均衡。

RabbitMQ介绍

RabbitMQ 是一个开源的消息代理软件(Message Broker),实现了高级消息队列协议(AMQP)。它用于在分布式系统中存储、转发消息,支持多种消息传递模式,如点对点、发布/订阅等。RabbitMQ 以其高可靠性、易扩展性和跨平台特性广泛应用于异步通信、削峰填谷、系统解耦等场景。

RabbitMQ工作模型

可以将消息队列的架构与MySQL数据库进行类比,便于理解其核心组件的作用:

  • Broker:类比为MySQL服务器,作为消息队列的核心服务端,负责接收、存储和转发消息。
  • Virtual Host:类似于数据库,用于实现不同业务或项目的逻辑隔离,确保各模块互不干扰。
  • Queue:对应数据库中的表,用于存储特定类型的消息,并按规则进行消息的投递和消费。
  • Message:相当于表中的一条记录,即实际传递的业务数据或任务信息。

这种隔离设计使得开发人员能够清晰地划分业务边界,便于维护和扩展,同时避免资源竞争或数据混乱的问题。

RabbitMQ 有四种主要的交换机类型

  1. Direct Exchange(直连交换机)
    根据消息携带的路由键(Routing Key)与交换机绑定的队列的绑定键(Binding Key)进行精确匹配,只有完全一致时才会将消息路由到对应队列。适合一对一的精准路由场景。必须是路由值和绑定键完全一致才可以发送成功

           

  1. Fanout Exchange(扇形交换机)
    不处理路由键,会将收到的消息广播到所有与它绑定的队列,忽略绑定键的设置。适合需要将消息同时发送到多个队列的广播场景(如日志分发)。大家可以理解成下图中展示方式:没有任何的路由规则,直接信息发送到所有和交换机连接的队列中。

          

  1. Topic Exchange(主题交换机)
    通过路由键和绑定键的模糊匹配(支持通配符 * 和 #* 匹配一个单词,# 匹配零个或多个单词)来路由消息。适合需要按类别或主题进行消息过滤和分发的场景(如按用户角色、地区分发消息)。他和直连交换机的区别就是他支持模糊匹配。

  2. Headers Exchange(首部交换机)
    不依赖路由键,而是根据消息的首部(Headers)属性进行匹配,通过绑定队列时设置的键值对规则判断是否路由。适合需要基于消息元数据(而非路由键)进行复杂匹配的场景,使用相对较少。

RabbitMQ的过期消息

通过消息属性设置单条消息的过期时间,若在指定时间内未被消费,系统自动删除该消息。

为整个队列设置 TTL,队列中所有消息继承该过期时间。

直接删除 RabbitMQ在消息过期后会直接从队列中删除,不会进入死信队列。这种情况下,消息会被丢弃,无法再被消费。

进入死信队列 如果消息队列系统配置了死信队列(Dead Letter Exchange, DLX),并且消息过期时间(TTL)到达后,消息会被路由到死信队列。死信队列可以用于后续处理或分析,避免消息丢失。

死信队列

死信队列(Dead Letter Queue, DLQ)是一种用于处理无法被正常消费的消息的机制。当消息因过期、被拒绝或消费失败达到最大重试次数、队列到达最大长度时,可将其转移到死信队列,避免直接丢失,便于后续人工干预或分析。

延迟交换机:

虽然RabbitMQ原生不支持延迟队列,但可以通过以下方法模拟实现延迟队列功能:

利用TTL+死信队列实现延迟队列

通过设置消息的TTL(Time To Live)和死信交换机(DLX)的组合可以实现延迟队列功能:

  1. 创建普通队列A,设置消息TTL和死信交换机参数
  2. 消息到达队列A后,在TTL过期前不会被消费
  3. 消息过期后会被转发到配置的死信交换机
  4. 死信交换机将消息路由到实际处理队列B

该方案存在的问题

  1. 消息阻塞问题
    当队列头部消息因TTL未到期而阻塞时,即使后面消息已到期也无法被及时处理。这是因为RabbitMQ仅会在消息到达队列头部时检查其是否过期。

  2. 定时精度问题
    消息实际投递时间可能存在延迟,不适合对时间精度要求严格的场景。

  3. 资源消耗问题
    大量延迟消息会堆积在队列中,占用系统资源。

  4. 监控复杂度增加
    需要额外监控死信队列和交换机的状态。

解决方案

为了解决这个问题,我们可以使用延迟交换机。 RabbitMQ ,通过延迟交换机通过插件(如 rabbitmq-delayed-message-exchange)实现。消息发布时指定延迟时间(x-delay 头),交换机将消息暂存,到期后投递到目标队列。

之后我们在创建交换机时就可以选择创建的是延迟交换机,我们发送消息之后,在没有到达时间的时候就会存储在数据库中,到达延迟时间之后,才会到达队列中。

消息的可靠性:

我们根据RabbitMQ的工作模型可以发现,消息在发送时可能会出现消息丢失的位置是在下图中标注的5个位置:

实际上,发送车和channel之间和接收者和channel之间是同一种情况,索引其实可以任务是4中情况。

confirm模式

RabbitMQ的Confirm模式是一种确保消息可靠投递的机制,生产者通过该模式确认消息是否成功到达Broker。与事务机制相比,Confirm模式性能更高,适合高吞吐场景。

Return模式

RabbitMQ的Return模式用于处理消息无法被正确路由到队列的情况。当消息通过basic.publish发送到交换机,但无法被路由到任何队列时(例如交换机类型为direct且没有匹配的绑定),Return模式会触发消息回退给生产者。

上面是传输中是否可以成功到达,下面我们需要考虑的是,如果到达之后时候需要进行持久化,如果没有持久化的话,服务器出现宕机时,我们的信息就会丢失:

交换机属性

  • Name:交换机的唯一标识符,由用户定义。
  • Durability:是否持久化交换机。持久化(durable=true)的交换机会在RabbitMQ重启后恢复。
  • Auto-delete:当所有队列解绑后是否自动删除交换机(auto-delete=true)。
  • Arguments:扩展参数,用于自定义行为(如TTL、死信配置等)。

备用交换机

备用交换机(Alternate Exchange,简称AE)用于处理无法被路由的消息。当消息无法被投递到目标队列时(通常因队列不存在或绑定不匹配),RabbitMQ会将消息转发到备用交换机,避免消息丢失。

队列属性

RabbitMQ队列属性用于定义队列的行为和特性,包括持久性、自动删除、消息TTL等。这些属性在声明队列时通过参数设置,直接影响消息的存储、传递和生命周期管理。

常用队列属性

x-message-ttl(消息生存时间)
设置队列中消息的最大存活时间(毫秒)。超过该时间未被消费的消息会自动被丢弃或死信。

x-expires(队列自动过期)
设置队列在未被使用时的自动删除时间(毫秒)。若队列在指定时间内未被访问(包括未被消费、绑定或声明),则自动删除。

x-max-length(最大消息数)
限制队列中消息的最大数量。超出限制时,旧消息会被丢弃或转移到死信队列。

x-dead-letter-exchange(死信交换机)
指定消息变为死信后转发的交换机。需配合死信路由键(x-dead-letter-routing-key)使用。

x-max-priority(消息优先级)
设置队列支持的最大优先级(0-255)。高优先级的消息会被优先消费。

上面是保证消息可靠性的基础,下面详解一下,消息的可靠性:

消息可靠性的设计

1.通过confirm保证消息到达交换机

2.通过return保证消息到达队列

3.交换机和队列中的消息进行持久化

4.手动ACK(消息确认)

下面是详细介绍

1. 生产者确认机制(Confirm)
通过publisher confirm机制确保消息成功到达交换机。生产者发送消息后,Broker(如RabbitMQ)会返回确认信号。若未收到确认,生产者可触发重试或补偿逻辑。

2. 队列路由监控(Return)
通过mandatoryreturn listener机制监听消息是否路由到队列。若消息无法路由到任何队列(如无绑定匹配),Broker会将消息返回给生产者,避免消息静默丢失。

3. 持久化存储
交换机和队列需显式声明为持久化(durable=true),消息投递时设置delivery_mode=2(持久化)。即使Broker重启,消息也不会丢失。注意:仅持久化不能完全避免丢失(如写入磁盘前崩溃)。

4. 消费者手动ACK
消费者处理完消息后需显式发送ACK确认。若处理失败或连接中断,Broker会将消息重新入队(需配置autoAck=false)。避免自动ACK导致消息未处理即被删除。

如何保证幂等性操作:

使用Redis实现幂等性操作

Redis可以通过其原子性操作和数据结构特性,有效保证幂等性。以下是具体实现方法:

基于SETNX命令 使用Redis的SETNX(SET if Not eXists)命令,将唯一ID作为key,操作状态作为value。如果key不存在则设置成功并执行操作,否则拒绝重复操作。


文章转载自:

http://bX45OvkL.rknsp.cn
http://Rrvb34bh.rknsp.cn
http://sWDA5gVv.rknsp.cn
http://hZjFemCg.rknsp.cn
http://alAr3AmH.rknsp.cn
http://ehmHTCx5.rknsp.cn
http://79iZitRT.rknsp.cn
http://RTtXkgH6.rknsp.cn
http://xwbZFQrb.rknsp.cn
http://qvGOdjoU.rknsp.cn
http://6gCsNqLg.rknsp.cn
http://3b6fbNgK.rknsp.cn
http://oITAjPjo.rknsp.cn
http://OuVHy0Xc.rknsp.cn
http://0OS3LyRy.rknsp.cn
http://ky9sowhg.rknsp.cn
http://phRxG5mm.rknsp.cn
http://0PPqIc1P.rknsp.cn
http://3FhrKBUR.rknsp.cn
http://lawzg7n1.rknsp.cn
http://SyYJiMqu.rknsp.cn
http://9VK8nfQg.rknsp.cn
http://KAGDAF6a.rknsp.cn
http://S3AV0osd.rknsp.cn
http://sv9JuMsW.rknsp.cn
http://tCspMEkg.rknsp.cn
http://IwLh1F2F.rknsp.cn
http://2P4xhRun.rknsp.cn
http://bHWAA6Eo.rknsp.cn
http://7xvoYw80.rknsp.cn
http://www.dtcms.com/a/383566.html

相关文章:

  • HBM4量产就绪|2026年AI与数据中心新标配
  • 细粒度图像分类的可解释性Finer-CAM
  • C++中多线程core的问题分析和总结
  • scrapy框架-day02
  • 电商导购平台的移动端架构设计:React Native在多端统一中的实践
  • class_9:java 抽象类和接口
  • [硬件电路-209]:电子携带两种能量,一种是电流宏观运动的动能,一种是绕着原子核运动的原子轨道能量;前者是电势能与热能转化的媒介;后者是实现光能与电能的转化
  • HBase启动报错“Master is initializing”解决方案
  • 交换机的级联和堆叠
  • QT加密和哈希
  • 历史数据分析——中科曙光
  • Dropout:深度学习中的随机丢弃正则化技术
  • 数组存储 · 行主序与列主序 | 应用 / 基地址 / 选择策略
  • 贪心算法应用:最早截止时间优先(EDF)问题详解
  • 每天五分钟深度学习:神经网络的权重参数如何初始化
  • BisenetV1/2网络以及模型推理转换
  • Codeforces Round 1050 (Div. 4)补题
  • 【Java后端】Spring Boot 多模块项目实战:从零搭建父工程与子模块
  • c++命名空间详解
  • 第15课:知识图谱与语义理解
  • HarmonyOS图形处理:Canvas绘制与动画开发实战
  • ffmpeg 有什么用处?
  • 如何重置Gitlab的root用户密码
  • LeetCode算法日记 - Day 41: 数据流的中位数、图像渲染
  • 计算机网络(二)物理层数据链路层
  • 零基础从头教学Linux(Day 33)
  • collections模块
  • 【前端】【高德地图WebJs】【知识体系搭建】图层知识点——>热力图,瓦片图层,自定义图层
  • 关系模型的数据结构
  • Spring Boot 与前端文件上传跨域问题:Multipart、CORS 与网关配置