MQ

MQ相关面试题以深入探究

Posted by YiBo on November 19, 2020

1. 为什么要使用消息队列?

解耦、异步、削峰

2. 消息队列推、拉模式区别?

push

客户端与服务器建立长连接

客户端可以及时收到消息

服务端不知道客户端的处理消息能力,可以出现消息积压

服务端保存发送状态以及负责负载均衡

pull

客户端主动从服务端轮询拉取数据

不及时

客户端保存状态(在故障重启时恢复)

客户端负责负载均衡(通过使用zookeeper)

3. 消息队列需要考虑的点

重复消费问题

消息保序性

消息持久化稳定性可靠性

消息一致性

4. 如何保证消息不被重复消费

幂等性:提过唯一的ID保障幂等性

通过redis SETNX 或者 mysql唯一主键约束

5. 消息队列消息丢失如何处理

  • 每条信息设置唯一的key
  • master - slave 异步 master - master 同步

6. 如何保证消息队列的高可用

7. 如何保证消息的顺序性

  • 确保消费者唯一
  • 采用单线程消费

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

  • rabbitmq

是可以设置过期时间的,就是TTL,如果消息在queue中积压超过一定时间就会被清理掉,大量数据直接搞丢

解决方法是能写个程序,将丢失的数据一点一点查出来,然后重新灌入MQ中

比如1个订单,其中1000个丢了,只能把1000个订单查出来,手动发送到MQ中再补一次

9. 大量消息在MQ里积压了几个小时还么解决

  • rabbitMQ

先修复consumer的问题,然后停掉

新建一个topic,partition设为原来的10倍

写一个临时分发数据的consumer,直接均有轮询写入临时建好的10倍数量的queue

q

10. 消息队列满了怎么办

  • rabbitMQ
    • 采用第9个问题的方案
    • 临时写程序,接入数据消费,消费一个丢弃一个,快速消费掉所有的消息,然后采用第8个问题的方案

11. 消息队列为什么会出现重复消费

rabbitMQ

  • 消费者消费后,返回确认信息前崩溃了
  • 采用topic广播模式

12. 消息如何保证可靠性

rocketMQ

一般消息中间件的消息传输保障分为三个等级:

  1. at most once 最多一次 消息可能会丢失,但绝不会重复
  2. at least once 最少一次,消息绝不会丢失,可能会重复
  3. exactly once 恰好一次

影响消息可靠性的几种情况:

  1. broker非正常关闭
  2. broker异常crash
  3. OS crash
  4. 机器掉电 但能立即供电
  5. 机器无法开启
  6. 磁盘损坏

1 2 3 4 属于硬件资源可立即回复情况,rocketMQ在这四种情况下能保证消息不丢(刷盘同步),或者99%少丢(刷盘异步)

5 6 属于单点故障,无法回复

通过双写技术可以完全避免单点,同步双写会影响性能,适合对消息可靠性要求极高的场合