RabbitMQ面试题整理

RabbitMQ面试题整理

1.RabbitMQ是什么?

​ RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的。

2.RabbitMQ 的使用场景有哪些

​ 抢购活动,削峰填谷,防止系统崩塌。

延迟信息处理,比如 10 分钟之后给下单未付款的用户发送邮件提醒。

解耦系统,对于新增的功能可以单独写模块扩展,比如用户确认评价之后,新增了给用户返积分的功能,这个时候不用在业务代码里添加新增积分的功能,只需要把新增积分的接口订阅确认评价的消息队列即可,后面再添加任何功能只需要订阅对应的消息队列即可。

3.RabbitMQ的特点?

可靠性:使用持久化和ACK消息确认机制来保证可靠性。

扩展性:多个RabbitMQ节点可以组成一个集群,可以根据实际业务需求动态扩展节点。

高可用性:队列可以在集群的基础上设置镜像,使得在部分节点失效的情况下保证队列仍旧可用。
灵活性:RabbitMQ几乎不受编程语言的限制,支持如Java、Python等常用编程语言。

4.RabbitMQ有哪些重要的角色

​ RabbitMQ 中重要的角色有:生产者、消费者和代理:

生产者:消息的创建者,负责创建和推送数据到消息服务器;

消费者:消息的接收方,用于处理数据和确认消息;

代理:就是 RabbitMQ 本身,用于扮演“快递”的角色,本身不生产消息,只是扮演“快递”的角色。

5.RabbitMQ 有哪些重要的组件

ConnectionFactory(连接管理器):应用程序与 Rabbit 之间建立连接的管理器,程序代码中使用。

Channel(信道):消息推送使用的通道。

Exchange(交换器):用于接受、分配消息。

Queue(队列):用于存储生产者的消息。

RoutingKey(路由键):用于把生成者的数据分配到交换器上。

BindingKey(绑定键):用于把交换器的消息绑定到队列上。

6. RabbitMQ 中 vhost 的作用是什么

​ vhost:每个 RabbitMQ 都能创建很多 vhost,我们称之为虚拟主机,每个虚拟主机其实都是 mini 版的 RabbitMQ,它拥有自己的队列,交换器和绑定,拥有自己的权限机制。

7.RabbitMQ 的消息是怎么发送的

​ 首先客户端必须连接到 RabbitMQ 服务器才能发布和消费消息,客户端和 rabbit server 之间会创建一个 tcp 连 接,一旦 tcp 打开并通过了认证(认证就是你发送给 rabbit 服务器的用户名和密码),你的客户端和 RabbitMQ 就创建了一条 amqp 信道(channel),信道是创建在“真实” tcp 上的虚拟连接,amqp 命令都是通过信道发送 出去的,每个信道都会有一个唯一的 id,不论是发布消息,订阅队列都是通过这个信道完成的。

8.RabbitMQ 怎么保证消息的稳定性

​ 生产者到RabbitMQ:事务机制和Confirm机制,注意:事务机制和 Confirm 机制是互斥的,两者不能共存,会导致 RabbitMQ 报错。

​ RabbitMQ自身:持久化、普通集群模式、镜像集群模式。

​ RabbitMQ到消费者:basicAck机制、死信队列、消息补偿机制。

9.RabbitMQ 怎么避免消息丢失

​ 把消息持久化磁盘,保证服务器重启消息不丢失。

​ 每个集群中至少有一个物理磁盘,保证消息落入磁盘。

10.RabbitMQ 要保证消息持久化成功的条件有哪些

1.声明队列必须设置持久化 durable 为 true.

2.消息推送投递模式必须设置持久化,deliveryMode 设置为 2(持久)。

​ 3.消息已经到达持久化交换器。

​ 4.消息已经到达持久化队列。

​ 前两步为持久化操作的两个步骤,以上四个条件都满足才能保证消息持久化成功。

11.RabbitMQ 持久化有什么缺点

​ 持久化的缺点就是降低了服务器的吞吐量,因为使用的是磁盘而非内存存储。可以使用 SSD 固态硬盘代替磁盘来尽可能减轻持久化带来的吞吐量问题。

12.RabbitMQ 有几种广播类型

​ direct(默认方式):最基础最简单的模式,发送方把消息发送给订阅方,如果有多个订阅者,默认采取轮询的方式进行消息发送。

​ headers:与 direct 类似,只是性能很差,此类型几乎用不到。

​ fanout:分发模式,把消费分发给所有订阅者。

​ topic:匹配订阅模式,使用正则匹配到消息队列,能匹配到的都能接收到。

13.RabbitMQ 怎么实现延迟消息队列

​ AMQP协议和RabbitMQ队列本身没有直接支持延迟队列功能,但是可以通过以下特性模拟出延迟队列的功能。

1、Time To Live(TTL)

​ RabbitMQ可以针对Queue设置x-expires 或者 针对Message设置 x-message-ttl,来控制消息的生存时间,如果超时(两者同时设置以最先到期的时间为准),则消息变为dead letter(死信)。

2、Dead Letter Exchanges(DLX)

​ RabbitMQ的Queue可以配置x-dead-letter-exchange 和x-dead-letter-routing-key(可选)两个参数,如果队列内出现了dead letter,则按照这两个参数重新路由转发到指定的队列。

14.死信队列?

​ DLX,全称为 Dead-Letter-Exchange,死信交换器,死信邮箱。当消息在一个队列中变成死信 (dead message) 之后,它能被重新被发送到另一个交换器中,这个交换器就是 DLX,绑定 DLX 的队列就称之为死信队列。

15.导致的死信的几种原因?
  • 消息被拒(Basic.Reject /Basic.Nack) 且 requeue = false。
  • 消息TTL过期。
  • 队列满了,无法再添加。
16.RabbitMQ 集群有什么用

​ 集群主要有以下两个用途:

​ 高可用:某个服务器出现问题,整个 RabbitMQ 还可以继续使用;

​ 高容量:集群可以承载更多的消息量

17.RabbitMQ 节点的类型有哪些

磁盘节点:消息会存储到磁盘。

内存节点:消息都存储在内存中,重启服务器消息丢失,性能高于磁盘类型。

18.RabbitMQ 集群搭建需要注意哪些问题

​ 各节点之间使用“–link”连接,此属性不能忽略。

​ 各节点使用的 erlang cookie 值必须相同,此值相当于“秘钥”的功能,用于各节点的认证。

​ 整个集群中必须包含一个磁盘节点。

​ 保证各个节点 erlang 版本一致:RabbitMQ 基于 erlang 语言,必须保证 各个节点 erlang 版本完全一致。

​ 可以跨操作系统建立集群。

19.RabbitMQ 每个节点是其他节点的完整拷贝吗为什么

​ 不是,原因有以下两个:

​ 存储空间的考虑:如果每个节点都拥有所有队列的完全拷贝,这样新增节点不但没有新增存储空间,反而增加了更多的冗余数据;

​ 性能的考虑:如果每条消息都需要完整拷贝到每一个集群节点,那新增节点并没有提升处理消息的能力,最多是保持和单节点相同的性能甚至是更糟。

20.RabbitMQ 集群中唯一一个磁盘节点崩溃了会发生什么情况

​ 如果唯一磁盘的磁盘节点崩溃了,不能进行以下操作:

  1. 不能创建队列
  2. 不能创建交换器
  3. 不能创建绑定
  4. 不能添加用户
  5. 不能更改权限
  6. 不能添加和删除集群节点

​ 唯一磁盘节点崩溃了,集群是可以保持运行的,但你不能更改任何东西。

21.RabbitMQ 对集群节点停止顺序有要求吗

​ RabbitMQ 对集群的停止的顺序是有要求的,应该先关闭内存节点,最后再关闭磁盘节点。如果顺序恰好相反的话, 可能会造成消息的丢失。

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

mandatory: true 返回消息给生产者。

mandatory: false 直接丢弃。

23.延迟队列?

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

24.优先级队列?

​ 优先级高的队列会先被消费。

​ 可以通过x-max-priority参数来实现。

​ 当消费速度大于生产速度且Broker没有堆积的情况下,优先级显得没有意义。

25.事务机制?

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

​ channel.txSelect 用于将当前的信道设置成事务模式。

​ channel.txCommit 用于提交事务 。

​ channel.txRollback 用于事务回滚,如果在事务提交执行之前由于 RabbitMQ 异常崩溃或者其他原因抛出异常,通过txRollback来回滚。

26.发送确认机制?

​ 生产者把信道设置为confirm确认模式,设置后,所有再改信道发布的消息都会被指定一个唯一的ID,一旦消息被投递到所有匹配的队列之后,RabbitMQ就会发送一个确认(Basic.Ack)给生产者(包含消息的唯一ID),这样生产者就知道消息到达对应的目的地了。

27.消费者某些原因无法处理当前接受的消息如何来拒绝?

​ channel .basicNack channel .basicReject

28.消息传输保证层级?

​ At most once: 最多一次。消息可能会丢失,但不会重复传输。

​ At least once: 最少一次。消息绝不会丢失,但可能会重复传输。

​ Exactly once: 恰好一次,每条消息肯定仅传输一次。

29.队列结构?

​ 通常由以下两部分组成?

​ rabbit_amqqueue_process:负责协议相关的消息处理,即接收生产者发布的消息、向消费者交付消息、处理消息的确认(包括生产端的 confirm和消费端的 ack) 等。

​ backing_queue:是消息存储的具体形式和引擎,并向 rabbit amqqueue process提供相关的接口以供调用,完成消息的存储以及可能的持久化工作等。

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

​ alpha: 消息内容(包括消息体、属性和 headers) 和消息索引都存储在内存中 。

​ beta: 消息内容保存在磁盘中,消息索引保存在内存中。

​ gamma: 消息内容保存在磁盘中,消息索引在磁盘和内存中都有 。

​ delta: 消息内容和索引都在磁盘中 。

31.如何保证RabbitMQ消息队列的高可用?

​ RabbitMQ 有三种模式:单机模式,普通集群模式,镜像集群模式。

​ 单机模式:就是demo级别的,一般就是你本地启动了玩玩儿的,没人生产用单机模式

​ 普通集群模式:意思就是在多台机器上启动多个RabbitMQ实例,每个机器启动一个。

​ 镜像集群模式:这种模式,才是所谓的RabbitMQ的高可用模式,跟普通集群模式不一样的是,你创建的queue,无论元数据(元数据指RabbitMQ的配置数据)还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。

32. RabbitMQ有什么优缺点?

**优点:**解耦、异步、削峰;

**缺点:**可能会降低系统的稳定性:在系统的业务功能和访问量需求足够的时候强行加入 RabbitMQ,如果消息队列出现问题,整个系统都会受到影响。因此,随意使用 RabbitMQ,可能会导致系统可用性降低。

增加了系统的复杂性:加入了消息队列,要多考虑很多方面的问题,比如:一致性问题、如何保证消息不被重复消费、如何保证消息可靠性传输等。因此,需要考虑的东西更多,复杂性增大。

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

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

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

针对以上问题,一个解决思路是:保证消息的唯一性,就算是多次传输,不要让消息的多次消费带来影响;保证消息等幂性;

比如:在写入消息队列的数据做唯一标识,消费消息时,根据唯一标识判断是否消费过;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值