抄答案就是了,两套详细的设计方案,解决头疼的支付掉单问题 (2)

抄答案就是了,两套详细的设计方案,解决头疼的支付掉单问题

这个方案主要流程跟定时方案类似,主要区别在于第四步,第五步,第八步。

第四步的流程从插入掉单表变更为往延迟队列发送掉单消息

第五步,补单程序接收掉单消息,然后触发支付掉单查询。

第八步,如果第七步支付结果查询为以下状态:

支付结果为扣款成功

支付结果为明确失败

掉单记录查询达到最大次数

补单程序将会告知延迟队列消费成功,延迟队列将会删除这条掉单消息。

其他状态将会告知消费失效,延迟队列将会在一定延时之后,再次发送掉单消息,然后继续重复第五步。

延迟队列

这里的延迟队列需要自己实现,复杂度还是比较高的,这里给大家推荐几种实现方案:

第一种,基于 Redis SortedSet 实现延迟队列。可以参考一下有赞的实现方案https://tech.youzan.com/queuing_delay/

第二种,基于时间轮算法(TimingWheel)实现延迟队列,具体可以参考 Kafka 延时队列。

第三种,基于 RocketMQ 延迟消息。

前两种方案说起来还需要再开发,所以还是比较复杂的。

这里重点说下第三种方案,该方案是 RocketMQ 已经支持的特性,开箱即用,使用起来还是比较简单的。

RocketMQ 延迟消息支持 18 个等级,分别如下:

1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h

消息发送方可以通过以下方式指定延迟等级,对应上方的延迟时间。

Message#setDelayTimeLevel

消息消费方,如果消费失败,默认将会在消息发送方的的延迟等级基础上加 1。如果消息消费方需要指定其他的延迟等级,可以使用如下方式:

ConsumeConcurrentlyContext#setDelayLevelWhenNextConsume

RocketMQ 延迟消息,支持的特性还是比较基础、简单,不支持自定义延迟时间。不过对于掉单补偿的这个场景刚好够用,但是如果需要自定义延迟的,那还是得采用其他的方案。

方案优缺点

延迟消息的方案相对于定时轮询方案来讲:

无需再查询全部订单,效率高

时效性较好

不过延迟消息这种方案,需要基于延迟队列,实现起来比较复杂,目前开源实现也比较少。

小结

支付掉单、卡单是支付过程中经常会碰到的事,我们可以采用异步补偿的方案,解决该问题。

异步补偿方案可以采用如下两种:

定时轮询补偿方案

延迟消息补偿方案

定时轮询补偿方案实现起来比较简单,但是时效性稍差。

而延迟消息补偿方案总体来说比较优秀,但是实现起来比较复杂。如果没有自定义的延迟时间的需求,可以直接采用 RocketMQ 延迟消息,简单快捷。

另外延迟队列使用场景还是比较多,不仅仅能用在掉单补偿上,还可以用于支付关单等场景。所以有能力开发的团队,可以开发一个通用的延迟队列、

好了,今天的文章就到这里了。

我是楼下小黑哥,下篇文章再见,886~

欢迎关注我的公众号:小黑十一点半,获得日常干货推送。如果您对我的专题内容感兴趣,也可以关注我的博客:studyidea.cn

历史支付文章推荐

钱被扣走了,但是订单却未成功!支付掉单异常最全解决方案

一笔订单,但是误付了两笔钱!这种重复付款异常到底该如何解决?

收款神器!解读聚合收款码背后的原理|原创

手机没网了,却还能支付,这是什么原理?|原创

轻轻一扫,立刻扣款,付款码背后的原理你不想知道吗?|原创

支付渠道路由系统进化史

从零开始设计对账系统

微信支付宝接入大全

多支付通道路由网关设计

银行卡支付,背后到底发生了什么?

欢迎关注我的公众号:小黑十一点半,获得日常干货推送。如果您对我的专题内容感兴趣,也可以关注我的博客:studyidea.cn

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

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