关于MQ的介绍以及常见问题

一、简介

MQ全称Message Queue 消息队列,是一种应用程序对应用程序的消息通信,一端只管住队列不断发布消息,另一端只管往队列中读取消息,发布者不需要关心读消息的是谁,读消息者不需要关心发布消息的是谁,各干各的互不干扰。

市场上现在常用的消息队列有: RabbitMQ、RocketMQ、Kafka、ActiveMQ

二、MQ的优势

1.解耦

使用消息MQ后,只需要保证消息格式不变,不需要关心消费者以及发布者之间的关系,这两者不需要彼此的联系。

2.异步

在一些不需要即使(同步)的返回结果操作,通过消息队列来实现异步。

3.削峰

在大量请求时(秒杀场景),使用消息队列做缓存处理,削弱峰值的流量,防止系统在短时间内被峰值流量冲垮。

例如场景:在大量流量涌入高峰,如数据库只能抗住2000的并发流量,可以使用MQ控制2000到数据库中。

4.日志处理

日志存储在消息队列中,用来处理日志,比如Kafka

三、MQ的劣势

1.系统的可用性降低

在还未引进MQ之前,系统只需要关系生产端与消费端的接口一致性就可以了,现在引进后,系统需要关注生产端、MQ与消费端的稳定性,这增加了系统的负担,系统运维成本增加。

2.系统的复杂性提高

引入了MQ,需要考虑的问题就增加了,如何去保证消息的一致性,消费者不被重复消费等问题。

3.一致性的问题

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),再重新检查,如被消费,则正常操作

如果还没有被消费,则抛出异常。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值