RabbitMQ常见面试题
Posted 啥也不懂的派大星
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RabbitMQ常见面试题相关的知识,希望对你有一定的参考价值。
目录
一、简述RabbitMQ的架构设计
![](https://image.cha138.com/20230303/e979165558d04686b72e931c490c7a9f.jpg)
交换器类型
direct 点对点:消息中的路由键和绑定规则中的路由key一致,交换器就会把消息发到对应的队列,是完全匹配才会发送,一个发送者和接收者,多个接受者我们用的点对点。
fanout 广播:每个fanout类型的交换器会将消息分发到所有绑定的队列上。不处理路由键 速度最快用的最多。
topic 通过模糊匹配分配消息的路由键。将路由键和某个模式进行匹配 单词 用点分割 *一个单词 # 多个单词。
header 性能较差,一般不用。二、RabbitMQ如何确保消息发送 ? 消息接收?
发送方确认机制
信道需要设置为 confirm 模式,则所有在信道上发布的消息都会分配一个唯一 ID。
一旦消息被投递到 queue(可持久化的消息需要写入磁盘),信道会发送一个确认给生产者(包含消息唯一ID )。 如果 RabbitMQ 发生内部错误从而导致消息丢失,会发送一条 nack (未确认)消息给生产者。 所有被发送的消息都将被 confirm (即 ack ) 或者被 nack 一次。 但是没有对消息被 confirm 的快慢做任何保证,并且同一条消息不会既被 confirm 又被 nack。 发送方确认模式是异步的,生产者应用程序在等待确认的同时,可以继续发送消息。当确认消息到达生产者,生产者的回调方法会被触发。 ConfirmCallback 接口:只确认是否正确到达 Exchange 中,成功到达则回调。 ReturnCallback 接口:消息失败返回时回调。接收方确认机制
消费者在声明队列时,可以指定noAck参数,当noAck=false时,RabbitMQ会等待消费者显式发回ack信号后才从内存(或者磁盘,持久化消息)中移去消息。否则,消息被消费后会被立即删除。
消费者接收每一条消息后都必须进行确认(消息接收和消息确认是两个不同操作)。只有消费者确认了消息, RabbitMQ 才能安全地把消息从队列中删除。 RabbitMQ 不会为未 ack的消息设置超时时间,它判断此消息是否需要重新投递给消费者的唯一依据是消费该消息的消费者连接是否已经断开。这么设计的原因是 RabbitMQ允许消费者消费一条消息的时间可以很长。保证数据的最终一致性; 如果消费者返回 ack 之前断开了链接, RabbitMQ 会重新分发给下一个订阅的消费者。(可能存在消息重复消费的隐患,需要去重)三、RabbitMQ事务消息
通过对信道的设置实现 1. channel.txSelect() ;通知服务器开启事务模式;服务端会返回 Tx.Select-Ok 2. channel.basicPublish ;发送消息,可以是多条,可以是消费消息提交 ack 3. channel.txCommit() 提交事务; 4. channel.txRollback() 回滚事务; 消费者使用事务: 1. autoAck=false ,手动提交 ack ,以事务提交或回滚为准; 2. autoAck=true,不支持事务的,也就是说你即使在收到消息之后在回滚事务也是于事无补的,队列已经把消息移除了。如果其中任意一个环节出现问题,就会抛出 IoException异常,用户可以拦截异常进行事务回滚,或决定要不要重复消息。 事务消息会降低 rabbitmq 的性能。四、RabbitMQ死信队列、延时队列
- 消息被消费方否定确认,使用 channel.basicNack 或 channel.basicReject ,并且此时requeue 属性被设置为 false 。
- 消息在队列的存活时间超过设置的TTL时间。
- 消息队列的消息数量已经超过最大队列长度。
五、Rabbitmq的持久化机制
- 交换机持久化:exchange_declare创建交互机时通过参数指定。
- 队列持久化:queue_declare创建队列时通过参数指定。
- 消息持久化:new AMQPMessage创建消息时通过参数指定。
六、RabbitMQ如何保证消息的可靠性传输
1、使用事务消息 2、使用消息确认机制 发送方确认: channel 设置为 confirm 模式,则每条消息会被分配一个唯一 id。 消息投递成功,信道会发送 ack 给生产者,包含了 id ,回调 ConfirmCallback 接口。 如果发生错误导致消息丢失,发生 nack 给生产者。回调 ReturnCallback 接口。 ack 和 nack 只有一个触发,且只有一次,异步触发。可以继续发送消息。 接收方确认: 声明队列时,指定 noack=false , broker 会等待消费者手动返回 ack、才会删除消息,否则立刻删除。 broker 的 ack 没有超时机制,只会判断链接是否断开,如果断开、消息会被重新发送。七、Rabbitmq的普通集群原理
![](https://image.cha138.com/20230303/a3ee7492179544e7bbf9501133f9606b.jpg)
节点直接同步元数据。
元数据
- 队列元数据:队列名称和它的属性。
- 交换器元数据:交换器名称、类型和属性。
- 绑定元数据:一张简单的表格展示了如何将消息路由到队列。
- vhost元数据:为vhost内的队列、交换器和绑定提供命名空间和安全属性。
为什么只同步元数据
存储空间,每一个节点都保存全量数据,影响消息堆积能力。 性能,消息的发布者需要将消息复制到每一个集群节点。 客户端连接的是非队列数据所在节点:则该节点会进行路由转发,包括发送和消费。集群节点类型
磁盘节点:将配置信息和元信息存储在磁盘上。 内存节点:将配置信息和元信息存储在内存中。性能优于磁盘节点。依赖磁盘节点进行持久化。 RabbitMQ要求集群中至少有一个磁盘节点,当节点加入和离开集群时,必须通知磁盘节点(如果集群中唯一的磁盘节点崩溃了,则不能进行创建队列、创建交换器、创建绑定、添加用户、更改权限、添加和删除集群节点)。如果唯一磁盘的磁盘节点崩溃,集群是可以保持运行的,但不能更改任何东西。因此建议在集群中设置两个磁盘节点,只要一个可以,就能正常操作。八、Rabbitmq的镜像队列原理
以上是关于RabbitMQ常见面试题的主要内容,如果未能解决你的问题,请参考以下文章