一、为何要引入MQ系统,直接读写数据库不行吗?
其实就是问问你消息队列都有哪些使用场景,而后你项目里具体是什么场景,说说你在这个场景里用消息队列是什么?html
面试官问你这个问题,指望的一个回答是说,大家公司有个什么业务场景,这个业务场景有个什么技术挑战,若是不用 MQ 可能会很麻烦,可是你如今用了 MQ 以后带给了你不少的好处。java
先说一下消息队列常见的使用场景吧,其实场景有不少,可是比较核心的有 3 个:解耦、异步、削峰。
解耦:多系统多进程的数据交换,用pub/sub
异步:把大数据量的同步处理改成异步
削峰:通常的A 系统使用 MySQL,扛到每秒 2k 个请求就差很少了,若是每秒请求到 5k 的话,可能就直接把 MySQL 给打死了,致使系统崩溃,用户也就无法再使用系统了。若是使用 MQ, 每秒 5k 个请求写入 MQ,A 系统每秒钟最多处理 2k 个请求,由于 MySQL 每秒钟最多处理 2k 个。A 系统从 MQ 中慢慢拉取请求,每秒钟就拉取 2k 个请求,不要超过本身每秒能处理的最 大请求数量就 ok,这样下来,哪怕是高峰期的时候,A 系统也绝对不会挂掉,这又设计请求排队的问题。git
二、消息队列有什么优缺点?
优势:解耦、异步、削峰
缺点:
系统可用性下降
系统引入的外部依赖越多,越容易挂掉。原本你就是 A 系统调用 BCD 三个系统的接口就行了,人 ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整,MQ 一挂,整套
系统崩溃的,你不就完了?github
系统复杂度提升
硬生生加个 MQ 进来,你怎么保证消息没有重复消费?怎么处理消息丢失的状况?怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已。面试
一致性问题
A 系统处理完了直接返回成功了,人都觉得你这个请求就成功了;可是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。redis
三、Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?
https://blog.csdn.net/Dome_/article/details/84990563数据库
四、RabbitMQ 的高可用性如何保证?
RabbitMQ 有三种模式:单机模式、普通集群模式、镜像集群模式
单机模式不存在高可用。
普通集群模式也不存在高可用性,意思就是在多台机器上启动多个 RabbitMQ 实例,每一个机器启动一个。可是你建立的 queue,只会放在一个 RabbitMQ 实例上,可是每一个实例都同步 queue 的元数据(元数据能够认为是 queue 的一些配置信息,经过元数据,能够找到 queue 所在实例)。你消费的时候,实际上若是链接到了另一个实例,那么那个实例会从 queue 所在实例上 拉取数据过来。这种方式确实很麻烦,也不怎么好,没作到所谓的分布式,就是个普通集群。由于这致使你要么消费者每次随机链接一个实例而后拉取数据,要么固定链接那个 queue 所在实 例消费数据,前者有数据拉取的开销,后者致使单实例性能瓶颈。并且若是那个放 queue 的实例宕机了,会致使接下来其余实例就没法从那个实例拉取,若是你开启了消息持久化,让 RabbitMQ 落地存储消息的话,消息不必定会丢,得等这个实例恢复了,而后才能够继续从这个 queue 拉取数据。
镜像集群模式的策略是高可用策略,指定的时候能够要求数据同步到全部节点的,也能够要求同步到指定数量的节点,再次建立 queue 的时候,应用这个策略,就会自动将数据同步到其余的 节点上去了。api
https://www.javazhiyin.com/22905.html缓存
五、如何解决消息队列的延时以及过时失效问题?
其实本质针对的场景,都是说,可能你的消费端出了问题,不消费了;或者消费的速度极其慢,形成消息堆积了,MQ存储快要爆了,甚至开始过时失效删除数据了。异步
针对这个问题能够有事前、事中、过后三种处理
六、RabbitMQ如何保证不丢数据?
须要考虑3个可能丢数据的地方:生产端、队列自己、消费端
设置持久化有两个步骤:
七、如何保证队列的消息不被重复消费?
这个须要灵活做答,考察的是思考力,由于消费的场景有不少,有数据库、有缓存、有第三方接口
八、集群节点类型都有什么?
节点的存储类型分为两种:
磁盘节点就是配置信息和元信息存储在磁盘上,内存节点把这些信息存储在内存中,固然内次节点的性能是大大超越磁盘节点的。单节点系统必须是磁盘节点,不然每次你重启RabbitMQ以后全部的系统配置信息都会丢失。RabbitMQ要求集群中至少有一个磁盘节点,当节点加入和离开集群时,必须通知磁盘节点。