MQ面试问题整理

项目中为什么使用MQ 优点

  1. 解耦

    同一块业务的相关能力被很多个项目需要,后续也有极大可能会被其他项目需要。将该部分能力解耦,通过MQ进行消息的统一处理。若有其他项目或业务需要相关功能,则对此进行订阅,处理相关业务。减少项目直接依赖。
  2. 异步

    大型项目相关协作人员,参与团队越来越多,项目之间的关联越来越深。造成整个链路特别长,且问题排查不容易。
  3. 削峰

    对于部分业务,在某些时间点,可能因为瞬时请求过大,造成所有请求直接访问至数据库对数据库造成压力,从而影响项目原有业务。一般MySQL数据库的处理能力在2k次/s,MQ的高峰处理能力1w+。能有效的处理

缺点
系统可用性降低 由于新增加了MQ,因为MQ的可用性、可靠性会造成系统可用性的额外负担。

  1. 可用性问题如何解决

    不同的MQ对此的解决方案不一样。
    ActiveMQ
    Zookeeper及多个activeMQ,修改持久化为性能更好的LevelDB替换掉默认的KahaDB.

    优点:简单实现了可用性。

    缺点:每次实际可用的MQ只有一个,一旦有一个MQ出现问题,相关的消息就会丢失。
RocketMQ
  • 单master模式,一旦出现问题,就会整个服务不可用。一般不会直接生产使用,适合个人学习;
  • 多master模式,多个master节点组成集群。单个master出现问题不影响。优点:所有模式中性能最高的。 缺点:单个master节点宕机期间,未被消费的消息在节点恢复之前不可用,消息实时性就受到影响。注意:使用同步刷盘可保证消息不丢失,同时topic相对应的queue应该分布在集权中各个master节点,而不是只在某一个master节点上;
  • 多master多slave异步复制模式,在多master模式下,每个master节点至少都有一个对应的slave;

    master节点可读可写,slave只可读 不可写。优点:在master宕机时,消费者可以直接从slave读取消息,消息实时性不会受到影响,性能几乎与多master一样。缺点:使用异步复制可能造成消息丢失问题。
  • 多master多slave同步双写,同上一种模式类似,区别在于master与slave之间的数据同步方式。优点:同步双写的同步模式能保证数据不丢失。缺点:发送单个消息时长会比较长,性能会比较差;
    同步刷盘,异步刷盘的区别:在于多master之间的数据同步写入磁盘模式。
同步复制 异步复制
概念 即等 Master 和 Slave 均写成功后才反馈给客户端写成功状态 只要 Master 写成功,就反馈客户端写成功状态
可靠性 可靠性高,若 Master 出现故障,Slave 上有全部的备份数据,容易恢复 若 Master 出现故障,可能存在一些数据还没来得及写入 Slave,可能会丢失
效率 由于是同步复制,会增加数据写入延迟,降低系统吞吐量 由于只要写入 Master 即可,故数据写入延迟较低,吞吐量较高
实际应用中的推荐把Master和Slave设置成ASYNC_FLUSH的异步刷盘方式,主从之间配置成SYNC_MASTER的同步复制方式,这样即使有一台机器出故障,仍然可以保证数据不丢。
  1. 可靠性问题如何解决

    引入MQ造成的数据可靠性问题,或者如何处理消息丢失问题?整个MQ的链路中,可能存在消息丢失的位置仅有三个,一个是生产端,一个是MQ自身,最后一个就是下游的消费者。

    不同的MQ对此解决方案均不一样,需分别分析。
ActiveMQ
生产端
程序在每次发往MQ的消息后,可接收到MQ对其的Ack响应,
系统复杂度提高 增加了MQ,引入了消息是否会重复消费,消息丢失问题。

数据一致性 引入MQ之后,单一事务会被分拆为多个事务。引入了分布式事务一致性的问题。

MQ如何处理重复消费问题 幂等校验
  • 上游不能重复下发

    程序自己保证不重复创建消息,使用业务事务进行控制。
  • 下游不能重复消费
  • 将消息信息入库,使用数据库、Redis进行消息存储。有消息过来使用唯一主键进行存储,每次进行校验是否存在,不存在继续处理,否则根据业务进行忽略或更新;
  • 将消息信息入库,根据业务进行唯一主键约束,若有重复数据,则会报唯一主键冲突,也插入不了;
  • 假如仅是redis的set操作,则无需处理。即时重复也不影响;
MQ如何处理消息丢失问题 【MQ面试问题整理】http://yannis.club

    推荐阅读