关于RabbitMQ一些面试题

网友投稿 606 2022-05-29

目录

0. 什么是RabbitMQ

1. 延时队列底层实现

2. 使用RabbitMQ需要注意什么

3. RabbitMQ效率

4. 插入延时队列的过期时间是单调的麻?

5. 如何确保消息正确地发送至RabbitMQ? 如何确保消息接收方消费了消息?

5.1 发送方确认模式

5.2 接收方确认机制

6. 如何避免消息重复投递或重复消费?

7. 消息基于什么传输?

8、消息如何分发?

9、消息怎么路由?

10、如何确保消息不丢失?

10.1 生产者丢失消息

10.2 RabbitMQ自己丢了数据

10.3 消费者弄丢了数据

11、RabbitMQ的集群

12、使用RabbitMQ有什么好处?

12.1 削峰

12.2 异步

12.3 解耦

13、MQ 的缺点

14、介绍Rabbitmq的手动ACK和自动ACK

参考连接

0. 什么是RabbitMQ

RabbitMQ采用AMQP高级新消息队列协议的一种消息队列技术,最大的特点是消费并不需要确保提供方实现,实现了服务之间的高度解耦

1. 延时队列底层实现

2. 使用RabbitMQ需要注意什么

3. RabbitMQ效率

关于RabbitMQ的一些面试题

4. 插入延时队列的过期时间是单调的麻?

5. 如何确保消息正确地发送至RabbitMQ? 如何确保消息接收方消费了消息?

5.1 发送方确认模式

将信道设置成confirm模式(发送方确认模式),则所有在信道上发布的消息都会被指派一个唯一ID。一旦消息被投递到目的队列后,或者消息被写入磁盘后,信道会发送一个确认给生产者(包括消息的ID)。

如果RabbitMQ发生内部错误从而导致消息丢失,会发送一条nack消息。

发送方确认模式是异步的,生产者应用程序在等待确认的同时,可以继续发送消息。

当确认消息到达生产者应用程序,生产者应用的回调方法就会被触发来处理确认消息。

5.2 接收方确认机制

消费者接受每一条消息后都必须进行确认,只要有消费者确认了消息,MQ才能安全的把消息从队列中删除。

这里并没有用到超时机制,MQ仅通过Consumer的连接中断来确认是否需要重新发送消息。也就是说,只要连接不中断,RabbitMQ给了Consumer足够长的时间来处理消息。保证了数据的最终一致性。

还有几种情况:

如果消费者接受到消息,在确认之前断开了连接或取消订阅,RabbitMQ会认为消息没有被分发,然后重新分发给下一个订阅的消费者。(可能存在消费重复的隐患,需要去重)

如果消费者接受到消息却没有确认消息,连接也未断开,则RabbitMQ认为该消费者繁忙。则不会给该消费者分发更多的消息。

6. 如何避免消息重复投递或重复消费?

在消息生产时,MQ内部针对每条生产者发送的消息生成一个inner-msg-id,作为去重的依据(消息投递失败并重传),避免重复的消息进入队列,在消息消费时,要求消息体中 必须要有一个bizID(对于同一个业务全局唯一) 作为去重的依据,避免同一条消息被重复消费。

7. 消息基于什么传输?

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

8、消息如何分发?

一个生产者,多个消费者

多个消费者时,是轮询机制,依次分发给消费者(每个消费者按顺序依次消费)

no_act设置是否确认消息处理完?

no_act = True , 消费者不发送确认信息,RabbitMQ从发送消息队列后,不管消费者是否处理完,删除queue

设置no_act=False,RabbitMQ等待消费者的callback处理完,发送确认信息,如果此时消费者down了,则RabbitMQ把消息轮询发送给下一个消费者,等待确认才会删除queue

去掉no_act=True,需要在回调函数中新增代码,手动向RabbitMQ发送确认信息

9、消息怎么路由?

Direct:直连模式

Topic: 转发模式

Topic 模式下可以使用统配符表示bingKey:’*'表示匹配一个单词, '#'则表示匹配没有或者多个单词。由此可以实现一个queue接收多个路由的消息。

Fanout :广播模式

广播模式下,不用理会routing key。Fanout Exchange 会将消息传递到 exchange 绑定好的 queue list 上去。

10、如何确保消息不丢失?

10.1 生产者丢失消息

可以选择使用 RabbitMQ 提供事务功能,就是生产者在发送数据之前开启事务,然后发送消息,如果消息没有成功被RabbitMQ接收到,那么生产者会受到异常报错,这时就可以回滚事物,然后尝试重新发送;如果收到了消息,那么就可以提交事物。

缺点: RabbitMQ 事务已开启,就会变为同步阻塞操作,生产者会阻塞等待是否发送成功,太耗性能会造成吞吐量的下降。

还有就是上面的第五点

10.2 RabbitMQ自己丢了数据

持久化

10.3 消费者弄丢了数据

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

11、RabbitMQ的集群

12、使用RabbitMQ有什么好处?

12.1 削峰

把消息压入RabbitMQ中可以缓冲系统压力。比如现在系统只能接受2000请求,但是一下子有10000个请求过来,那么这个请求就会压在RabbitMQ中,那么就可以慢慢进行消费了。

12.2 异步

以前是先去发短信,再去发邮件。引入RabbitMQ之后,我们就可以进行在发短信的同时再去发邮箱。

12.3 解耦

当多个系统耦合在一起的时候,系统的消息会发送给连在一起的系统,但是这个消息有些系统可能是不需要的。所以引入了之后,很方便将这个系统进行解耦,每个系统需要的就在消息队列解耦。

13、MQ 的缺点

虽然能提供削峰,异步,解耦,但是这个还是有很多要考虑的问题,消息丢失,重复消费。

14、介绍Rabbitmq的手动ACK和自动ACK

当消息一旦被消费者接收,队列中的消息就会被删除。那么问题来了:RabbitMQ怎么知道消息被接收了呢?

这就要通过消息确认机制(Acknowlege)来实现了。当消费者获取消息后,会向RabbitMQ发送回执ACK,告知消息已经被接收。不过这种回执ACK分两种情况:

自动ACK:消息一旦被接收,消费者自动发送ACK

手动ACK:消息接收后,不会发送ACK,需要手动调用

这两ACK要怎么选择呢?这需要看消息的重要性:

如果消息不太重要,丢失也没有影响,那么自动ACK会比较方便

如果消息非常重要,不容丢失。那么最好在消费完成后手动ACK,否则接收消息后就自动ACK,RabbitMQ就会把消息从队列中删除。如果此时消费者宕机,那么消息就丢失了。

参考连接

分布式消息中间件-RabbitMQ面试题(必问)

RabbitMQ-解耦、异步、削峰

HTTP RabbitMQ

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:docker打包 commit和Dockerfile
下一篇:汶川大地震已过十一年,我仍记忆犹新
相关文章

 发表评论

暂时没有评论,来抢沙发吧~