【业务场景设计】超时时间和用户等待支付时间的关系

大家好,我是仰望-星空~~。因为上一篇文章还在酝酿中,所以决定先写这篇文章,顺序不同而已,质量还是有保证的。今天不讲具体代码的实现,讲讲业务场景的设计实现。

在很多电商业务场景中,抢购、下单、支付都是很普遍的场景,但是其中的设计是比较复杂的。今天我们来说说超时订单。

一、简介

说到超时订单,可能大多数人的想到就是能够实现超时处理的那些技术,比如说RabbitMQ、Redis的延时队列。对于Redis的延时队列的实际使用我并不是特别了解,因为它并不常用,而且有着较大的弊端(八股文上说的)。

那我们就说说RabbitMQ,RabbitMQ本身并不支持延时队列,但可以用TTL+死信队列来模拟延时队列的实现

  • TTL:过期时间,消息在队列中的超时时间
  • 死信队列:一个正常的队列,只不过它专门用来处理上一个队列中被拒绝、超时的消息。

延时队列的模拟:

创建队列A、B

我给A设置过期时间、容纳消息的最大值,队列B不进行任何设置;让A绑定B,以参数的形式设置B为死信处理队列。但消息被拒绝或者消息超时时,B就会接收到A中的消息进行处理。这就是延时消息的模拟实现。

这里需要注意一个点:超时时间只是消息等待被消费者处理的时间,不是用户等待支付的时间。

二、需求分析

1、如何实现订单超时处理呢?

我们知道TTL只是队列等待消费者消费的等待时间,如果指定消费者,无论消息最后是否被确认,TTL都会失效,换言之,如果没有出现其他异常,消息不会进入到死信队列中。也就意味着,消息在队列中的等待时间和用户的支付等待时间没有任何关系。

2、那我们的订单超时处理又是如何实现的呢?

经过长时间的思考和不断推演,我得出这样一个结论:

  • 首先TTL是可以处理超时订单的,不然它就没有被设计出来的必要

  • 其次消息发送时,一定不是只有一个队列接收

  • 第三,TTL就是用户等待支付时间,,之所以没达到预期效果,是因为我的思考缺了一些重要的环节

既然消息被消费者监听,超时时间就会失效,那我们就不设置消费者监听

3、那这样消息不都过期了吗?直接进入死信队列了

目的就是让消息全部过期,但未必都会被进行超时处理

我创建两个队列

  • A用于存储订单,设置超时时间,并绑定死信队列

  • B用于后续的业务处理,并绑定死信队列

既然A中消息是存储的订单ID,并设置了超时时间,要想使用。那我们就不监听A,同时用B来处理消息

4、那这两个队列又没有关联,如何得到想要的效果?而且如果用户支付了,那A中的消息最后还是会进入到死信队列中,订单最后被删除,又不能删除消息

关键:选择让所有的消息过期,通过订单状态来设置是否超时

MQ中是不提供删除消息的,只有消息被拒绝或者正常丢弃,但这都不是存储队列的作用

所以,转换思维,从订单的状态入手。订单在创建时是处于“未支付”状态,还有其他的状态

那我就设置消费者监听队列B,进行正常的订单创建和库存扣减,这时候订单处于“未支付”状态。

然后再进行下一步的支付流程。

5、那你又会问了,那不是所有的用户都要等待TTL,才能算成功支付吗?

换个角度来说,这样说没问题。但是仔细想想,TTL和用户支付成功之间是没关系的。

用户成功支付后,订单状态就变成“已支付”,当然这个订单的ID最后还是会进入死信队列中,我们会先进行判断,是否订单的状态为“已支付”,订单状态已改变,那最后就不会被删除。已付款订单和TTL之间也就没关系了。

如果用户没有立即支付,那订单就处于等待支付状态(消息进入超时等待)

如果未支付,进入死信队列,那就直接超时被处理

如果支付成功,那就直接跳过。

三、流程解析

这是我思考后,形成的一个消息处理流程图

根据我上面分析的,来总结一下处理流程:

1、首先创建四个队列A(订单存储)和B(订单处理)、C(订单结果队列)、D(死信队列)

2、A只存储消息,设置超时时间,不设置消费者,B处理业务逻辑,AB都绑定D,

3、订单交换机同时绑定AB,商品抢购成功后,将参数信息以消息的信息发送给订单交换机,订单交换机路由到AB中(这里有点类似于广播交换机,也可以通过设置相同的路由键来实现广播)

4、消息在A中的超时时间生效,消费者监听B,B中进行订单创建和库存扣减逻辑,如果中途出现异常,导致消息被拒绝,直接进入死信队列。

5、B中业务处理完成,订单为“未支付”状态,下一步进行远程支付逻辑

6、支付若完成,修改订单状态为“已支付”状态,支付OK。

7、A中消息超时,全部进入死信队列中,订单状态查询,若还未支付,设置为“超时状态”,若已支付,跳过。异步下单支付结束。

8、死信队列中主要是进行一些订单状态修改和库存、预库存回补逻辑

注意:此时B的业务逻辑处理和A是相关的,A中的超时时间也就等同于用户的等待支付时间。

回看整篇文章,其实它都是在解决一个问题:如何让消息超时时间TTL等于用户支付等待时间?

这个其实我想了很久的一段时间,其中也查阅了网上不少资料,但大多都是简单说说订单超时处理的解决方案。并没有讲清楚用户等待超时和消息超时之间的关系,也没有说明具体的流程,很容易让人摸不着头脑。

这是我想到的基于RabbitMQ实现订单超时处理唯一一个可行的方案,当然应该还有其他的方案,等我更加牛逼之后再分享吧!

具体的代码实现就交给大家自己完成吧,代码逻辑都给出了,实现起来应该没啥问题。

这里附上一张商品秒杀下单的完整架构图,凑合看吧😄

我的分享结束,欢迎大家点赞、评论、关注,我们下期见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值