一 、为什么使用消息队列
此问题主要从两方面回答:
1、消息队列的使用场景
解耦、异步任务、流量削峰。
场景1: 解耦
接口调用发送。假设现在要新增子系统E或删除其中某一个子系统,那么A系统都需要做程序修改。此时存在这样的问题:A系统与其它的子系统产生了严重的耦合。
解决案:使用 MQ,A 系统产生一条数据,发送到 MQ 里面去,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样下来,A 系统压根儿不需要去考虑要给谁发送数据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况。
场景2: 异步任务
现象:用户向A系统发送请求,并且还需要在ABCD写库操作,假设A系统写库需要3ms,其它子系统分别需要300ms、450ms、200ms,最终请求将需要953ms,此时存在这样的问题:用户体验非常慢。
解决案:使用 MQ,用户向A系统发送请求3ms,A系统连续发送3条消息到队列需要5ms,最终请求只需要8ms。
场景3: 流量削峰
现象:在高峰期,某一时间段向A系统发送的并发请求达到5k+/s个,假设数据库只能处理2k/s个请求,此时存在的问题:有可能造成数据库崩溃,系统宕机。
解决案:使用MQ,将所有的请求发送到队列,A 系统慢慢的按照每秒钟最多2k 个请求(因为数据库只能处理2k个)处理,等高峰期过后,A系统就会快速的解决积压的请求。
2、项目中使用过哪些消息队列,在什么场景下
根据项目实战回答。
二、消息队列的优缺点
优点:同上。
缺点:
①系统复杂度变高。(主要考虑三个问题:消息怎么不会被重复消费、如何保证消息不会缺失、如何保证消息的顺序性)
②系统可用性降低。(本来ABCD四个系统好好运行,结果添加个MQ进来,万一MQ出现问题,将造成ABCD四个系统不可用。)
③ 数据一致性问题。(因为执行的是异步任务,A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?这数据就不一致了。)
三、几种常用的消息队列的比较。
四、如何保证消息的高可用性
从管理控制台中的集群模式策略谈。包括三种模式:单机模式、普通集群模式、镜像集群模式(此模式才能保证高可用性)
镜像集群模式:在此种下,你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,就是说,每个 RabbitMQ 节点都有这个 queue 的一个完整镜像,包含 queue 的全部数据的意思。然后每次你写消息到 queue 的时候,都会自动把消息同步到多个实例的 queue 上