RabbitMQ工作原理以及常见面试题【2022版】

article/2025/10/22 10:24:44

RabbitMQ工作原理图:

Broker:接收和分发消息的应用,RabbitMQ Server 就是 Message Broker

Virtual host:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类似 于网络中的 namespace 概念。当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,可以划分出 多个 vhost,每个用户在自己的 vhost 创建 exchange/queue 等

Connection:publisher/consumer 和 broker 之间的 TCP 连接

Channel:如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP Connection 的开销将是巨大的,效率也较低。Channel 是在 connection 内部建立的逻辑连接,如果应用程 序支持多线程,通常每个 thread 创建单独的 channel 进行通讯,AMQP method 包含了 channel id 帮助客 户端和 message broker 识别 channel,所以 channel 之间是完全隔离的。Channel 作为轻量级的 Connection 极大减少了操作系统建立 TCP connection 的开销。

Exchange:message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发 消息到 queue 中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast)。

Queue:消息最终被送到这里等待 consumer 取走。

Binding:exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key,Binding 信息被保 存到 exchange 中的查询表中,用于 message 的分发依据 。

问:RabbitMQ是什么?

 一款采用AMQP(高级消息队列协议)的消息队列技术,用于在分布式系统中存储和转发消息。通过消息队列可以实现服务之间的高度解耦、异步通信、流量削峰。

通俗的来讲是:RabbitMQ 是一个消息中间件:它接受并转发消息。你可以把它当做一个快递站点,当你要发送一个包 裹时,你把你的包裹放到快递站,快递员最终会把你的快递送到收件人那里,按照这种逻辑 RabbitMQ 是 一个快递站,一个快递员帮你传递快件。RabbitMQ 与快递站的主要区别在于,它不处理快件而是接收, 存储和转发消息数据。


问:RabbitMQ 的工作模式

  1. simple 模式(即最简单的收发模式)

  2. work 工作模式(资源的竞争)

  3. publish/subscribe 发布订阅(共享资源)

  4. routing 路由模式

  5. topic 主题模式


问:说一说生产者与消费者模式。

所谓生产者-消费者问题,实际上主要是包含了两类线程。一种是生产者线程用于生产数据,另一种是消费者线程用于消费数据,为了解耦生产者和消费者的关系,通常会采用共享的数据区域,就像是一个仓库。生产者生产数据之后直接放置在共享数据区中,并不需要关心消费者的行为。而消费者只需要从共享数据区中去获取数据,就不再需要关心生产者的行为。但是,这个共享数据区域中应该具备这样的线程间并发协作的功能:

  1. 如果共享数据区已满的话,阻塞生产者继续生产数据放置入内;

  2. 如果共享数据区为空的话,阻塞消费者继续消费数据。


问:消息基于什么传输?

我们应该都是知道,网络数据传输协议TCP的性能并不高,因为它要求通信双方首先建立连接,才能正常进行数据通信。如果RabbitMQ使用TCP传输数据的话,频繁的TCP连接创建和销毁开销会很大。所以RabbitMQ使用信道(它是建立在真实的TCP连接内的虚拟连接)的方式来传输数据。 


问:什么是死信队列?如何导致的? 

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

应用场景:为了保证订单业务的消息数据不丢失,需要使用到 RabbitMQ 的死信队列机制,当消息 消费发生异常时,将消息投入死信队列中.还有比如说: 用户在商城下单成功并点击去支付后在指定时 间未支付时自动失效

死信来源(导致死信原因):

  1. 消息 TTL 过期
  2. 队列达到最大长度(队列满了,无法再添加数据到 mq 中)
  3. 消息被拒绝(basic.reject 或 basic.nack)并且 requeue=false.

 


问:什么是延迟队列?RabbitMQ 怎么实现延迟队列?使用场景? 

延时队列:队列内部是有序的,最重要的特性就体现在它的延时属性上,延时队列中的元素是希望 在指定时间到了以后或之前取出和处理,简单来说,延时队列就是用来存放需要在指定时间被处理的 元素的队列。

实现延迟消息,一般有两种方式: 

  1. 通过RabbitMQ本身队列的特性来实现,需要使用RabbitMQ的死信交换机(Exchange)和消息的存活时间TTL(Time To Live)。导致的问题:如果使用在消息属性上设置 TTL 的方式,消 息可能并不会按时“死亡“,因为 RabbitMQ 只会检查第一个消息是否过期,如果过期则丢到死信队列, 如果第一个消息的延时时长很长,而第二个消息的延时时长很短,第二个消息并不会优先得到执行。
  2. 在RabbitMQ 3.5.7及以上的版本提供了一个插件(rabbitmq-delayed-message-exchange)来实现延迟队列功能。同时,插件依赖Erlang/OPT 18.0及以上。

延迟队列使用场景:

  1. 订单在十分钟之内未支付则自动取消
  2. 新创建的店铺,如果在十天内都没有上传过商品,则自动发送消息提醒。
  3. 用户注册成功后,如果三天内没有登陆则进行短信提醒。
  4. 用户发起退款,如果三天内没有得到处理则通知相关运营人员。
  5. 预定会议后,需要在预定的时间点前十分钟通知各个与会人员参加会议

问:什么是优先级队列?

 RabbitMQ 自 V3.5.0 有优先级队列实现,优先级高的队列会先被消费。

可以通过x-max-priority参数来实现优先级队列。不过,当消费速度大于生产速度且 Broker 没有堆积的情况下,优先级显得没有意义。

 问:消息队列如何保证消息不丢?

丢数据一般分为两种,一种是mq把消息丢了,一种就是消费时将消息丢了。下面从rabbitmq丢失数据的场景。

RabbitMQ丢失消息分为如下几种情况:

  1. 生产者丢消息:

    生产者将数据发送到RabbitMQ的时候,可能在传输过程中因为网络等问题而将数据弄丢了。

  2. RabbitMQ自己丢消息:

    如果没有开启RabbitMQ的持久化,那么RabbitMQ一旦重启数据就丢了。所以必须开启持久化将消息持久化到磁盘,这样就算RabbitMQ挂了,恢复之后会自动读取之前存储的数据,一般数据不会丢失。除非极其罕见的情况,RabbitMQ还没来得及持久化自己就挂了,这样可能导致一部分数据丢失。

  3. 消费端丢消息:

    主要是因为消费者消费时,刚消费到还没有处理,结果消费者就挂了,这样你重启之后,RabbitMQ就认为你已经消费过了,然后就丢了数据。

针对上述三种情况,RabbitMQ可以采用如下方式避免消息丢失:

  1. 生产者丢消息:

    • 可以选择使用RabbitMQ提供是事务功能,就是生产者在发送数据之前开启事务,然后发送消息,如果消息没有成功被RabbitMQ接收到,那么生产者会受到异常报错,这时就可以回滚事务,然后尝试重新发送。如果收到了消息,那么就可以提交事务。这种方式有明显的缺点,即RabbitMQ事务开启后,就会变为同步阻塞操作,生产者会阻塞等待是否发送成功,太耗性能会造成吞吐量的下降。

    • 可以开启confirm模式。在生产者那里设置开启了confirm模式之后,每次写的消息都会分配一个唯一的id,然后如何写入了RabbitMQ之中,RabbitMQ会给你回传一个ack消息,告诉你这个消息发送OK了。如果RabbitMQ没能处理这个消息,会回调你一个nack接口,告诉你这个消息失败了,你可以进行重试。而且你可以结合这个机制知道自己在内存里维护每个消息的id,如果超过一定时间还没接收到这个消息的回调,那么你可以进行重发。

    事务机制是同步的,你提交了一个事物之后会阻塞住,但是confirm机制是异步的,发送消息之后可以接着发送下一个消息,然后RabbitMQ会回调告知成功与否。 一般在生产者这块避免丢失,都是用confirm机制。

  2. RabbitMQ自己丢消息:

    设置消息持久化到磁盘,设置持久化有两个步骤:

    • 创建queue的时候将其设置为持久化的,这样就可以保证RabbitMQ持久化queue的元数据,但是不会持久化queue里面的数据。

    • 发送消息的时候讲消息的deliveryMode设置为2,这样消息就会被设为持久化方式,此时RabbitMQ就会将消息持久化到磁盘上。 必须要同时开启这两个才可以。

    而且持久化可以跟生产的confirm机制配合起来,只有消息持久化到了磁盘之后,才会通知生产者ack,这样就算是在持久化之前RabbitMQ挂了,数据丢了,生产者收不到ack回调也会进行消息重发。

  3. 消费端丢消息:

    使用RabbitMQ提供的ack机制,首先关闭RabbitMQ的自动ack,然后每次在确保处理完这个消息之后,在代码里手动调用ack。这样就可以避免消息还没有处理完就ack。

 

 


http://chatgpt.dhexx.cn/article/RxoCj4sV.shtml

相关文章

RabbitMQ原理简单介绍

其实这篇博客,也算不上是什么原理,只是将我知道的一些RabbitMQ的知识简单罗列下,自从我来公司到现在,虽然一直都在用RabbitMQ,也一直想着把这块总结下,却一直在给自己找借口,最近一段时间&#…

MQ - RabbitMQ - 架构及工作原理

参考网址: RabbitMQ的应用场景以及基本原理介绍 RabbitMQ使用详解 RabbitMQ的Java应用(1) -- Rabbit Java Client使用 1. 系统架构 几个概念说明: Broker:它提供一种传输服务,它的角色就是维护一条从生产者到消费者的路线,保证数据能按照指定的方式进…

RabbitMQ 详解

RabbitMQ 详解 MQ 的相关概念RabbitMQ 四大核心概念RabbitMQ 的工作原理RabbitMQ 六大核心部分(模式)简单模式工作模式工作模式案例消息确认(消息应答)消息持久化 发布确认模式交换机(Exchange)Exchange 概…

RabbitMq原理及应用

一、简介 MQ(Message Queue),即消息队列,是一种实现应用级别之间的通信手段。不同应用之间可以通过读写消息,以消息为媒介传递应用数据,不需要应用之间建立强连接。此方式与远程调用(RPC)是应用通信的常见方式。在这个…

RabbitMQ原理解析

场景模拟 在介绍RabbitMQ之前,我们先来看下面一个电商项目的场景: 商品的原始数据保存在数据库中,增删改查都在数据库中完成。搜索服务数据来源是索引库(Elasticsearch),如果数据库商品发生变化&#xff0…

Rabbitmq基本原理和架构

全栈工程师开发手册 (作者:栾鹏) 架构系列文章 rabbitmq官网:https://www.rabbitmq.com/rabbitmqctl.8.html MQ全称为Message Queue, 是一种分布式应用程序的的通信方法,它是消费-生产者模型的一个典型的代表,produc…

RabbitMQ — RabbitMQ使用以及原理解析

RabbitMQ使用以及原理解析 RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现;在RabbitMQ官网上主要有这样的模块信息, Work queues消息队列,Publish/Subscribe发布订阅服务,Routing, Topics, RPC等主要应用的模块功能. 几个概念说明: Broker:它提供一种传…

RabbitMQ介绍及工作原理

RabbitMQ介绍及工作原理 一,什么是RabbitMQ ​ RabbitMQ是一种称为消息代理或队列管理器的消息队列软件。它是一个可以定义队列的软件,应用程序可以连接到队列并将消息传输到它们。消息队列的基本体系结构很简单:存在称为生产者的客户端应用…

彻底理解RabbitMQ底层原理

1.RabbitMQ概念 RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。 AMQP :Advanced Message Queue,高级消息队列协议。它是应用层协议的一个开放标准 ,为 面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息&…

rabbitmq消息队列原理

一、rabbitmq架构 RabbitMQ是一个流行的开源消息队列系统,是AMQP(高级消息队列协议)标准的实现,由以高性能、健壮、可伸缩性出名的Erlang语言开发,并继承了这些优点。rabbitmq简单架构如下: 上图简单展…

SpringBoot整合RabbitMQ及其原理分析

上一篇&#xff1a;RabbitMQ基础知识 1、相关依赖 这里无需指定版本号&#xff0c;让其跟着SpringBoot版本走。本示例使用SpringBoot版本号为2.7.10。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-…

rabbitmq详解

rabbitmq 一、简介二、业务场景1、异步2、应用解耦3、流量削峰 三、下载四、界面认识五、五种模型示例0、springboot依赖配置1、Hello World简单模型2、Work queues工作队列3、Publish/Subscribe发布订阅模型4、Routing路由模型5、Topics主题模型6、消息转换器 六、进阶1、消费…

[RabbitMQ--1] MQ简介

目录 1.MQ 的相关概念 1.1.什么是 MQ&#xff1f; 1.2.为什么要用MQ&#xff1f;MQ的应用场景 1.2.1.流量消峰&#xff1a; 1.2.2.任务异步处理&#xff1a; 1.2.3.应用解耦 2.AMQP和JMS 3.MQ 的分类 1.ActiveMQ 2.Kafka 3..RocketMQ 4..RabbitMQ 4.RabbitMQ 1.四…

什么是RabbitMq?其原理?

什么是RabbitMq&#xff1f; RabbitMQ是一个实现了AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;高级消息队列协议的消息队列服务&#xff0c;用Erlang语言。 rabbitmq原理 1.Producer&#xff1a;即数据的发送方。创建消息并将其发布(发送)到代理服务器 一…

RabbitMQ原理详解

RabbitMQ&#xff1a;我们通常谈到消息队列&#xff0c;就会联想到这其中的三者&#xff1a;生产者、消费者和消息队列&#xff0c;生产者将消息发送到消息队列&#xff0c;消费者从消息队列中获取消息进行处理。对于RabbitMQ&#xff0c;它在此基础上做了一层抽象&#xff0c;…

你应该知道的 9 种 前端设计模式

本篇文章给大家介绍 9 种 前端设计模式。有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对大家有所帮助。 什么是设计模式&#xff1f; 设计模式是对软件设计开发过程中反复出现的某类问题的通用解决方案。设计模式更多的是指导思想和方法论&#xff…

前端需要了解的设计模式

什么是设计模式&#xff1f; 设计模式是对软件设计开发过程中反复出现的某类问题的通用解决方案。设计模式更多的是指导思想和方法论&#xff0c;而不是现成的代码&#xff0c;当然每种设计模式都有每种语言中的具体实现方式。学习设计模式更多的是理解各种模式的内在思想和解…

前端设计模式应用

前端设计模式应用 什么是设计模式 软件设计中常见问题的解决方案模型: 历史经验的总结与特定语言无关 设计模式背景 模式语言:城镇、建筑、建造 (A Pattern Language:Towns, Buildings,Construction)1977设计模式:可复用面向对象软件的基础 (Design Patterns: Elements of …

web端设计和web前端开发的区别

Web前端开发技术主要包括三个要素&#xff1a;HTML、CSS和JavaScript&#xff01; 它要求前端开发工程师不仅要掌握基本的Web前端开发技术&#xff0c;网站性能优化、SEO和服务器端的基础知识&#xff0c;而且要学会运用各种工具进行辅助开发以及理论层面的知识&#xff0c;包括…

前端开发中常用设计模式-总结篇

本文是向大家介绍前端开发中常用的设计模式&#xff0c;它使我们编写的代码更容易被复用&#xff0c;也更容易被人理解&#xff0c;并且保证代码的稳定可靠性。 1.什么是设计模式 通俗来讲&#xff0c;就是日常使用设计的一种惯性思维。 因为对应的这种思维&#xff0c;以及对…