MQ必问面试题:为何会产生重复消息,你是如何解决的

MQ在互联网公司中是广泛应用的,也是程序员必备技能,在MQ的开发运维中,重复消息问题必然都会遇到,只有真正做过的同学才能讲出重复消息发生的原因,并给出相应的解决方案。

重复消息怎么回事

这要从MQ的机制说起,MQ最基本功能要保证产生和接收到消息,并把消息发送出去,所以它在实现的时候一般有这些功能:消息超时重传或者等待确认等机制,这样会使得消息会重复发送,那么重复发送就会产生重复消息。

可能产生的原因分析

参考下图:

从生产者这端分析如下:

  1. 首先消息生产者把消息发送给了消息队列,正常情况下,消息队列收到之后会产生一个应答,告诉生产者已经收到消息。如果此时队列出现了问题,没有产生应答,那么生产者很可能会发生请求重试,这就产生了重复消息。
  2. 消息队列中间件无问题,但是负载高,响应变慢了,导致生产者等待确认太久,导致生产者又重复发送消息。
  3. 网络故障导致生产者发起重试,也有可能产生重复消息

综述,生产者发送消息到MQ过程中,由于各种原因,收不到应答消息,触发了生产者的重试功能,而产生重复消息。

从消费者这端分析如下:

  1. 基本原因跟生产者端原因基本一致,就是消息队列往消费者投递消息时候产生重复,消费者应用来不及处理消息,没及时产生响应,导致队列不知道处理结果,而重复投递。
  2. 消费者响应了消息,此事消息队列出问题了,导致响应丢失,那么消息队列可能又把积压的数据重复投递。

综述,消费者消息过程中,反馈消费状态,由于各种原因,导致消息队列无法更新投递状态,触发的重试功能,而产生重复消息。

解决办法

采用幂等操作,什么是幂等操作?举2个sql例子就明白了

update tableA set num=10 where id =1

update tableA set num=num+10 where id =1

第一条sql语句,无论执行多少次,num都等于10,也就是对num字段来说,执行多次sql没影响,所以称为幂等操作。第二条语句,则相反,每次执行,num都会变化,所以称为非幂等操作。

实际操作过程中,实现幂等操作有几种方式

  1. 乐观锁:生产者发送消息要更新数据时候,要带上一个数据版本号,消费者去更新数据时候,就去比较版本号,版本号不一致,则操作失败,且每个版本号只有一次执行成功的机会,如果失败,生产者则必须重新获取最新的版本号。
  2. 去重表:利用数据库表的特性实现幂等操作。例如做一个唯一id字段,关联某一类的数据操作,后续有同一个操作,就不再处理。例如电商平台的订单id可以作为唯一id字段,我们做一个扣款操作,我们要保证合理的时间范围内此id的消息不会重复消费。

总结一下

我们用去重表的时候,其实可以把id放在缓存中,每次去检查id时候,可以从缓存获取,从而减轻数据库的压力。

发表评论
留言与评论(共有 0 条评论)
   
验证码:

相关文章

推荐文章

'); })();