秒杀系统要如何设计? (9)

在生产者发送mq消息之前,先把该条消息写入消息发送表,初始状态是待处理,然后再发送mq消息。消费者消费消息时,处理完业务逻辑之后,再回调生产者的一个接口,修改消息状态为已处理。

如果生产者把消息写入消息发送表之后,再发送mq消息到mq服务端的过程中失败了,造成了消息丢失。

这时候,要如何处理呢?

答:使用job,增加重试机制。

秒杀系统要如何设计?

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

8.2 重复消费问题

本来消费者消费消息时,在ack应答的时候,如果网络超时,本身就可能会消费重复的消息。但由于消息发送者增加了重试机制,会导致消费者重复消息的概率增大。

那么,如何解决重复消息问题呢?

答:加一张消息处理表。

秒杀系统要如何设计?

消费者读到消息之后,先判断一下消息处理表,是否存在该消息,如果存在,表示是重复消费,则直接返回。如果不存在,则进行下单操作,接着将该消息写入消息处理表中,再返回。

有个比较关键的点是:下单和写消息处理表,要放在同一个事务中,保证原子操作。

8.3 垃圾消息问题

这套方案表面上看起来没有问题,但如果出现了消息消费失败的情况。比如:由于某些原因,消息消费者下单一直失败,一直不能回调状态变更接口,这样job会不停的重试发消息。最后,会产生大量的垃圾消息。

那么,如何解决这个问题呢?

秒杀系统要如何设计?

每次在job重试时,需要先判断一下消息发送表中该消息的发送次数是否达到最大限制,如果达到了,则直接返回。如果没有达到,则将次数加1,然后发送消息。

这样如果出现异常,只会产生少量的垃圾消息,不会影响到正常的业务。

8.4 延迟消费问题

通常情况下,如果用户秒杀成功了,下单之后,在15分钟之内还未完成支付的话,该订单会被自动取消,回退库存。

那么,在15分钟内未完成支付,订单被自动取消的功能,要如何实现呢?

我们首先想到的可能是job,因为它比较简单。

job有个问题,需要每隔一段时间处理一次,实时性不太好。

还有更好的方案?

答:使用延迟队列。

我们都知道rocketmq,自带了延迟队列的功能。

秒杀系统要如何设计?

下单时消息生产者会先生成订单,此时状态为待支付,然后会向延迟队列中发一条消息。达到了延迟时间,消息消费者读取消息之后,会查询该订单的状态是否为待支付。如果是待支付状态,则会更新订单状态为取消状态。如果不是待支付状态,说明该订单已经支付过了,则直接返回。

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

秒杀系统要如何设计?


 

9 如何限流?

通过秒杀活动,如果我们运气爆棚,可能会用非常低的价格买到不错的商品(这种概率堪比买福利彩票中大奖)。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzwywj.html