面试必备(背)-RabbitMQ八股文系列!

464次阅读  |  发布于2年以前

什么是 RabbitMQ ?

什么是 AMQP ?

RabbitMQ 就是 AMQP 协议的 Erlang 的实现(当然 RabbitMQ 还支持 STOMP2、 MQTT3 等协议 ) AMQP 的模型架构和 RabbitMQ 的模型架构是一样的,生产者将消息发送给交换器,交换器和队列绑定 。

RabbitMQ 中的交换器、交换器类型、队列、绑定、路由键等都是遵循的 AMQP 协议中相 应的概念。目前 RabbitMQ 最新版本默认支持的是 AMQP 0-9-1。

说下 AMQP 协议三层?

AMQP 模型的几大组件?

为什么要使用rabbitmq

使用rabbitmq的场景

RabbitMQ 的优缺点?

优点:

缺点:

RabbitMQ 的构造

(1)生产者Publisher:生产消息,就是投递消息的一方。消息一般包含两个部分:消息体(payload)和标签(Label)。

(2)消费者Consumer:消费消息,也就是接收消息的一方。消费者连接到RabbitMQ服务器,并订阅到队列上。消费消息时只消费消息体,丢弃标签。

(3)Broker服务节点:表示消息队列服务器实体。一般情况下一个Broker可以看做一个RabbitMQ服务器。

(4)Queue:消息队列,用来存放消息。一个消息可投入一个或多个队列,多个消费者可以订阅同一队列,这时队列中的消息会被平摊(轮询)给多个消费者进行处理。

(5)Exchange:交换器,接受生产者发送的消息,根据路由键将消息路由到绑定的队列上。

(6)Routing Key:路由关键字,用于指定这个消息的路由规则,需要与交换器类型和绑定键(Binding Key)联合使用才能最终生效。

(7)Binding:绑定,通过绑定将交换器和队列关联起来,一般会指定一个BindingKey,通过BindingKey,交换器就知道将消息路由给哪个队列了。

(8)Connection :网络连接,比如一个TCP连接,用于连接到具体broker。

(9)Channel:信道,AMQP 命令都是在信道中进行的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为建立和销毁 TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接,一个TCP连接可以用多个信道。客户端可以建立多个channel,每个channel表示一个会话任务。

(10)Message:消息,由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。

(11)Virtual host:虚拟主机,用于逻辑隔离,表示一批独立的交换器、消息队列和相关对象。一个Virtual host可以有若干个Exchange和Queue,同一个Virtual host不能有同名的Exchange或Queue。最重要的是,其拥有独立的权限系统,可以做到 vhost 范围的用户控制。当然,从 RabbitMQ 的全局角度,vhost 可以作为不同权限隔离的手段。

RabbitMQ 中的 broker、cluster 是指什么?

RabbitMQ 概念里的 channel、exchange 和 queue 是逻辑概念,还是对应着进程实体?分别起什么作用?

由 AMQP 协议描述可知,channel 是真实 TCP 连接之上的虚拟连接,所有 AMQP 命令都是通过 channel 发送的,且每一个 channel 有唯一的 ID。一个 channel 只能被单独一个操作系统线程使用,故投递到特定 channel 上的 message 是有顺序的。但一个操作系统线程上允许使用多个 channel

消息基于什么传输?

由于TCP连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶颈。RabbitMQ 使用信道的方式来传输数据。信道是建立在真实的TCP连接内的虚拟连接,且每条TCP连接上的信道数量没有限制

消息如何分发?

若该队列至少有一个消费者订阅,消息将以循环(round-robin)的方式发送给消费者。每条消息只会分发给一个订阅的消费者(前提是消费者能够正常处理消息并进行确认)

生产者消息运转?

  1. Producer先连接到Broker,建立连接Connection,开启一个信道(Channel)。
  2. Producer声明一个交换器并设置好相关属性。
  3. Producer声明一个队列并设置好相关属性。
  4. Producer通过路由键将交换器和队列绑定起来。
  5. Producer发送消息到Broker,其中包含路由键、交换器等信息。
  6. 相应的交换器根据接收到的路由键查找匹配的队列。
  7. 如果找到,将消息存入对应的队列,如果没有找到,会根据生产者的配置丢弃或者退回给生产者。
  8. 关闭信道。
  9. 管理连接。

消费者接收消息过程?

  1. Producer先连接到Broker,建立连接Connection,开启一个信道(Channel)。
  2. 向Broker请求消费响应的队列中消息,可能会设置响应的回调函数。
  3. 等待Broker回应并投递相应队列中的消息,接收消息。
  4. 消费者确认收到的消息,ack。
  5. RabbitMq从队列中删除已经确定的消息。
  6. 关闭信道。
  7. 关闭连接。

交换器无法根据自身类型和路由键找到符合条件队列时,有哪些处理?

如何确保消息正确地发送至RabbitMQ?

  • 将信道设置成confirm模式(发送方确认模式),则所有在信道上发布的消息都会被指派一个唯一的ID
  • 一旦消息被投递到目的队列后,或者消息被写入磁盘后(可持久化的消息),信道会发送一个确认给生产者(包含消息唯一ID)
  • 如果RabbitMQ发生内部错误从而导致消息丢失,会发送一条nack(not acknowledged,未确认)消息
  • 发送方确认模式是异步的,生产者应用程序在等待确认的同时,可以继续发送消息。当确认消息到达生产者应用程序,生产者应用程序的回调方法就会被触发来处理确认消息

如何确保消息接收方消费了消息?

  • 接收方消息确认机制:消费者接收每一条消息后都必须进行确认(消息接收和消息确认是两个不同操作)
  • 只有消费者确认了消息,RabbitMQ才能安全地把消息从队列中删除 这里并没有用到超时机制,RabbitMQ 仅通过 Consumer 的连接中断来确认是否需要重新发送消息
  • 也就是说,只要连接不中断,RabbitMQ 给了 Consumer 足够长的时间来处理消息

下面列出几种特殊情况:

  • 如果消费者接收到消息,在确认之前断开了连接或取消订阅,RabbitMQ 会认为消息没有被分发,然后重新分发给下一个订阅的消费者。(可能存在消息重复消费的隐患,需要根据bizId去重)
  • 如果消费者接收到消息却没有确认消息,连接也未断开,则RabbitMQ认为 该消费者繁忙,将不会给该消费者分发更多的消息

如何保证 RabbitMQ 的高可用?

没有哪个项目会搭建一台 RabbitMQ 服务器提供服务,风险太大;

如何保证消息的可靠性?

消息到MQ的过程中搞丢,MQ自己搞丢,MQ到消费过程中搞丢。

如何保证 RabbitMQ 不被重复消费?

先说为什么会重复消费:正常情况下,消费者在消费消息的时候,消费完毕后,会发送一个确认消息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除;

但是因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将消息分发给其他的消费者

如何保证 RabbitMQ 消息的可靠传输?

消息不可靠的情况可能是消息丢失,劫持等原因;

丢失又分为:

生产者丢失消息:

transaction机制就是说:

confirm 模式用的居多:一旦 channel 进入 confirm 模式,所有在该信道上发布的消息都将会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后;

rabbitMQ 就会发送一个 ACK 给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了;

如果rabbitMQ没能处理该消息,则会发送一个Nack消息给你,你可以进行重试操作。

消息列表丢失消息:

那么如何持久化呢?

消费者丢失消息:

如何保证RabbitMQ消息的顺序性?

解决方法就是保证生产者入队的顺序是有序的,出队后的顺序消费则交给消费者去保证。

消息怎么路由?

从概念上来说,消息路由必须有三部分:交换器、路由、绑定

常用的交换器主要分为以下三种:

特别注意:发往 topic 交换器的消息不能随意的设置选择键(routing_key),必须是由"."隔开的一系列的标识符组成。

什么是元数据?元数据分为哪些类型?

1 . 在非 cluster 模式下:

元数据主要分为

2 . 在 cluster 模式下:

在单node 系统和多 node 构成的 cluster 系统中声明 queue、exchange ,以及进行 binding 会有什么不同?

死信队列&死信交换器

DLX 全称(Dead-Letter-Exchange),称之为死信交换器 当消息变成一个死信之后,如果这个消息所在的队列存在x-dead-letter-exchange参数,那么它会被发送到x-dead-letter-exchange对应值的交换器上,这个交换器就称之为死信交换器,与这个死信交换器绑定的队列就是死信队列

消息在什么时候会变成死信?

延迟队列?

存储对应的延迟消息,指当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。

优先级队列?

事务机制?

RabbitMQ 客户端中与事务机制相关的方法有三个:

如何解决消息队列的延时以及过期失效问题?

RabbtiMQ 是可以设置过期时间的,也就是 TTL。如果消息在 queue 中积压超过一定的时间就会被 RabbitMQ 给清理掉,这个数据就没了。这就不是说数据会大量积压在 mq 里,而是大量的数据会直接搞丢。我们可以进行批量重导。

就是大量积压的时候,直接丢弃数据,然后等过了高峰期以后,比如晚上12点以后,将丢失的那批数据,写个临时程序,然后重新灌入 mq 里面去,手动发到 mq 里去再补一次。

消息传输保证层级?

Virtual Host

每一个 RabbitMQ 服务器都能创建虚拟的消息服务器,也叫虚拟主机(virtual host),简称vhost。 默认为“/”。

RabbitMQ中消息可能有的几种状态?

消息队列满了以后该怎么处理?

临时写程序,接入数据来消费,消费一个丢弃一个,都不要了,快速消费掉所有的消息。然后等过了高峰期以后再补数据。

有几百万消息持续积压几小时,怎么办?

消息积压处理办法:临时紧急扩容:

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8