关于MQ常见问题汇总

MQ常见问题

上次梳理秒杀架构的时候,说到了关于mq的一些问题,这里进行一下梳理记录。

1、消息丢失问题

在往MQ发送消息的时候,很可能会发送失败,原因有很多,比如:网络问题、broker挂了、mq服务端磁盘问题等。这些情况,都可能会造成消息丢失。
那么,如何防止消息丢失呢?
答:加一张消息发送表。

关于MQ常见问题汇总

在生产者发送mq消息之前,先把该条消息写入消息发送表,初始状态是待处理,然后再发送mq消息。消费者消费消息时,处理完业务逻辑之后,再回调生产者的一个接口,修改消息状态为已处理。
如果生产者把消息写入消息发送表之后,再发送mq消息到mq服务端的过程中失败了,造成了消息丢失。 这时候,要如何处理呢?
答:使用定时任务xxl-job,增加重试机制。

定时扫表 发送mq消息 xxl-job 查询记录表中状态为待处理的数据 mq服务

用job每隔一段时间去查询消息发送表中状态为待处理的数据,然后重新发送mq消息。

2、重复消费问题

本来消费者消费消息时,在ack应答的时候,如果网络超时,本身就可能会消费重复的消息。但由于消息发送者增加了重试机制,会导致消费者重复消息的概率增大。
那么,如何解决重复消息问题呢? 答:加一张消息处理表。

关于MQ常见问题汇总

消费者读到消息之后,先判断一下消息处理表,是否存在该消息,如果存在,表示是重复消费,则直接返回。如果不存在,则进行下单操作,接着将该消息写入消息处理表中,再返回。
有个比较关键的点是:下单和写消息处理表,要放在同一个事务中,保证原子操作。

3、垃圾消息问题

这套方案表面上看起来没有问题,但如果出现了消息消费失败的情况。比如:由于某些原因,消息消费者下单一直失败,一直不能回调状态变更接口,这样job会不停的重试发消息。最后,会产生大量的垃圾消息。
那么,如何解决这个问题呢?
答:每次在job重试时,需要先判断一下消息发送表中该消息的发送次数是否达到最大限制,如果达到了,则直接返回。如果没有达到,则将次数加1,然后发送消息。
这样如果出现异常,只会产生少量的垃圾消息,不会影响到正常的业务。

关于MQ常见问题汇总

4、延迟消费问题

通常情况下,如果用户秒杀成功了,下单之后,在15分钟之内还未完成支付的话,该订单会被自动取消,回退库存。
那么,在15分钟内未完成支付,订单被自动取消的功能,要如何实现呢? 我们首先想到的可能是job,因为它比较简单。
但job有个问题,需要每隔一段时间处理一次,实时性不太好。 还有更好的方案?
答:使用延迟队列。
我们都知道rocketmq,自带了延迟队列的功能。
下单时消息生产者会先生成订单,此时状态为待支付,然后会向延迟队列中发一条消息。达到了延迟时间,消息消费者读取消息之后,会查询该订单的状态是否为待支付。如果是待支付状态,则会更新订单状态为取消状态。如果不是待支付状态,说明该订单已经支付过了,则直接返回。

关于MQ常见问题汇总

还有个关键点,用户完成支付之后,会修改订单状态为已支付。

关于MQ常见问题汇总

以上是对mq的四个问题及处理方法,能力正在进步,希望能帮助到大家!

上一篇:PEnum_MaintenanceType


下一篇:HM-SpringCloud微服务系列4.2【RabbitMQ快速入门】