一、简介
MQ 全称为 Message Queue- 音讯队列,是一种应用程序对应用程序的音讯通信,一端只管往队列一直公布信息,另一端只管往队列中读取音讯,发布者不须要关怀读取音讯的谁,读取音讯者不须要关怀公布音讯的是谁,各干各的互不烦扰。
市场上当初罕用的音讯队列有:RabbitMQ、RocketMQ、Kafka,ActiveMQ
二、MQ 的劣势
(1) 解耦
应用音讯 MQ 后,只须要保障音讯格局不变,不须要关怀发布者及消费者之间的关系,这两者不须要彼此分割
(2) 异步
在一些不须要即时 (同步) 的返回后果操作,通过音讯队列来实现异步。
(3) 削峰
在大量申请时(秒杀场景),应用音讯队列做缓冲解决,减弱峰值流量,避免零碎在短时间内被峰值流量冲垮。
场景:在大量流量涌入顶峰,如数据库只能抗住 2000 的并发流量,能够应用 MQ 管制 2000 到数据库中
(4) 日志解决
日志存储在音讯队列中,用来解决日志,比方 kafka。
三、MQ 的劣势
- 零碎的可用性升高
在还未引进 MQ 之前,零碎只须要关系生产端与生产端的接口一致性就能够了,当初引进后,零碎须要关注生产端、MQ 与生产端三者的稳定性,这减少零碎的累赘,零碎运维成本增加。
- 零碎的复杂性进步
引入了 MQ,须要思考的问题就减少了,如何保障音讯的一致性,生产不被反复生产等问题,
- 一致性问题
A 零碎发送完音讯间接返回胜利,然而 BCD 零碎之中若有零碎写库失败,则会产生数据不统一的问题。
四、常见问题
(1) 怎么保障音讯没有反复生产?应用音讯队列如何保障幂等性
幂等性:就是用户对于同一操作发动的一次申请或者屡次申请的后果是统一的,不会因为屡次点击而产生了副作用
问题呈现起因
咱们先来理解一下产生音讯反复生产的起因,对于 MQ 的应用,有三个角色:生产者、MQ、消费者,那么音讯的反复这三者会呈现:
- 生产者:生产者可能会推送反复的数据到 MQ 中,有可能 controller 接口反复提交了两次,也可能是重试机制导致的
- MQ:假如网络呈现了稳定,消费者生产完一条音讯后,发送 ack 时,MQ 还没来得及承受,忽然挂了,导致 MQ 认为消费者还未生产该条音讯,MQ 回复后会再次推送了这条音讯,导致呈现反复生产。
- 消费者:消费者接管到音讯后,正筹备发送 ack 到 MQ,忽然消费者挂了,还没得及发送 ack,这时 MQ 认为消费者还没生产该音讯,消费者重启后,MQ 再次推送该条音讯。
解决方案
在失常状况下,生产者是客户,咱们很难避免出现用户反复点击的状况,而 MQ 是容许存在多条一样的音讯,但消费者是不容许呈现生产两条一样的数据,所以幂等性个别是在生产端实现的:
- 状态判断:消费者把生产音讯记录到 redis 中,再次生产时先到 redis 判断是否存在该数据,存在则示意生产过,间接抛弃
- 业务判断:生产完数据后,都是须要插入到数据库中,应用数据库的惟一束缚避免反复生产。插入数据库前先查问是否存在该数据,存在则间接抛弃音讯,这种形式是比较简单粗犷地解决问题
(2) 音讯失落的状况
(3) 音讯的传输程序性
解决思路
在生产端公布音讯时,每次法公布音讯都把上一条音讯的 ID 记录到音讯体中,消费者接管到音讯时,做如下操作
- 先依据上一条 Id 去查看是否存在上一条音讯还没被生产,如果不存在(生产后去掉 id),则失常进行,如果失常操作
- 如果存在,则依据 id 到数据库查看是否被生产,如果被生产,则失常操作
- 如果还没被生产,则休眠肯定工夫(比方 30ms),再从新查看,如被生产,则失常操作
- 如果还没被生产,则抛出异样