消息中间件MQ场景常见问题(消息丢失,重复消费,垃圾消息,延时消费)

消息中间件MQ场景常见问题(消息丢失,重复消费,垃圾消息,延时消费),第1张

消息中间件MQ场景常见问题(消息丢失,重复消费,垃圾消息,延时消费) 消息中间件MQ场景问题及解决办法

目录
  • 消息中间件MQ场景问题及解决办法
  • 问题背景
  • 一、消息丢失问题
  • 二、消息重复消费问题
  • 三、垃圾消息问题
  • 四、延时消费问题
  • 总结


问题背景

业务场景:秒杀 ——> 下单 ——> 支付
这三个核心流程中,真正并发量大的是秒杀功能,下单和支付功能实际并发量很小。
所以,我们在设计秒杀系统时,有必要把下单和支付功能从秒杀的主流程中拆分出来,
特别是下单功能要做成mq异步处理的。而支付功能,比如支付宝支付,是业务场景本身保证的异步。


一、消息丢失问题

问题背景:上一步秒杀 *** 作成功了,发送消息的时候出现网络问题或broker挂了等原因,导致消息发送失败,造成消息丢失
解决办法:增加一张消息发送表
具体实现:在生产者发送消息到mq之前,先把这条消息写入消息发送表,消息初始状态是待处理,后在发送mq消息,消费者消费消息时,处理完业务逻辑之后,再回调生产者这个接口,修改消息状态为已处理。
遗留问题:如果生产者已经把消息写入消息发送表了,再发送消息到mq服务端的过程失败了,造成了 消息的丢失,如何处理?
解决办法:使用job,增加重试机制
具体实现:用job,每隔一段时间去查询消息发送表中状态为待处理的数据,然后重新发送mq消息。
遗留问题:那这样是不是也有可能消息被重复消费?


二、消息重复消费问题

问题背景:如果我们设置了ack机制,当出现网络问题时,ack应答超时,本身就有可能造成消息重复消费,而且我们还设置了job,定时重新发送消息,这样使消息的重复消费的几率大大增加。
解决办法:增加一张消息处理表
具体实现:消费者读到消息之后,先判断一下消息处理表,是否存在该消息,如果存在,表示重复消费,则直接返回。 如果不存在,则进行正常 *** 作,接着将消息写入消息处理表中,再返回。
注意点: 进行正常业务逻辑 *** 作和将消息写入消息处理表中,这个两个 *** 作要放在一个事务当中,保证原子性。


三、垃圾消息问题

问题背景:上面逻辑看着没啥大问题,但是如果出现消息消费失败的情况。比如:由于某些原因,消 息消费者下单一直失败,一直不能回调状态变更接口,job一直重试,最后导致大量垃圾消息
解决办法:设置发送消息次数
具体实现:每次在job重试的时候,需要判断一下消息发送表中该消息的发送次数是否到达最大限制,如果达到了最大限制,直接返回。如果没有达到,则将次数+1,然后发送消息。这样如果出现异常,也只会产生少量的垃圾消息,不会影响到正常的业务。


四、延时消费问题

问题背景:用户秒杀成功,下单之后,30分钟之内未进行支付,该订单会被自动取消,回退库存。
实现方法可以用job,但job有个问题,需要每隔一段时间处理一次,实时性不是很好我们还可以用延时队列,rocketMq自带了延时队列的功能
具体实现:下单时消息生产者会生成一张订单,此时的状态为待支付,然后向延时队列中发送一条消息,当到达延时时间,消息消费者读取消息之后,会查询该订单的状态是否为待支付。如 果是待支付状态,则更新订单状态为取消状态。如果不是待支付,说明该订单已经支付过了,则直接返回;
注意点: 用户完成支付之后,会修改订单状态为已支付。


总结

这个场景也是会经常遇到的,看到别人的总结,感觉思路不错,整理一下,以后遇到其他的场景也可以有自己思路。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5442924.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存