抄答案就是了,两套详细的设计方案,解决头疼的支付掉单问题
Hello,大家好,我是楼下小黑哥~
好久没写支付相关的文章了,今天继续从事老本行~
上次在文章钱被扣走了,但是订单却未成功!支付掉单异常最全解决方案提到,支付过程会出现掉单、卡单的情况,这种情况对于用户来讲,体验非常差,明明自己付了钱,扣了款,但是订单却未成功。
上篇文章我们简单说了下解决方案,这次小黑哥就结合生产实际碰到的情况,给出两种详细设计的方案:
- 定时轮询补偿方案
- 延迟消息补偿方案
大家可以根据自己系统的实际情况,选择性参考。
当然了,以下设计方案可能并不完美,如果各位读者还有其他解决方案,欢迎留言指出,一起讨论,一起成长~
欢迎关注我的公众号:小黑十一点半,获得日常干货推送。如果您对我的专题内容感兴趣,也可以关注我的博客:studyidea.cn
定时轮询补偿方案
整体流程
这个方案主要采用定时任务,批量查询掉单记录,从而驱动查询具体支付支付结果,然后更新内部订单。
整体方案流程图如下:
前三步流程没什么好说的,正常的支付流程,咱们针对后面几步具体详细说下。
第三步调用支付通道之后,如果支付通道端返回支付受理成功或者支付处理中,我们就需要调用第四步,将这类订单插入掉单表。
如果支付直接成功了,那就正常流程返回即可。
复习一下,网关类支付,比如支付宝、微信支付、网银支付,这种支付模式,支付通道仅仅返回支付受理成功,具体支付结果需要接收支付通道端的支付通知,这类支付我们将其称为异步支付。
相应的还有同步支付,比如银行卡支付,微信、支付宝代扣类支付,这类支付,同步就能返回支付结果。
第五步,补单应用将会定时查询数据库,批量查询掉单记录。
第六步,补单应用使用线程池,多线程异步的方式发起掉单查询。
第七步,调用支付通道支付查询接口。
重点来了,如果第七步支付结果查询为以下状态:
- 支付结果为扣款成功
- 支付结果为明确失败
- 掉单记录查询达到最大次数
第八步就会删除掉单记录。
最后,如果掉单查询依旧还是处理中,那么经过一定的延时之后,重复第五步,再次重新掉单补偿,直到成功或者查询到达最大次数。
相关问题
为什么需要新建一张掉单表?不能直接使用支付订单表,查询未成功的订单吗?
这个问题,实际上确实可以直接使用的支付订单表,然后批量查询当天未成功的订单,补单程序发起支付查询。
那为什么需要新建一张掉单表?
主要是因为数据库查询效率问题,因为支付订单表每天都会大量记录新增,随着时间,这张表记录将会越来越多,越来越大。
支付记录越多,批量范围查询效率就会变低,查询速度将会变慢。
所以为了查询效率,新建一张掉单表。
这张表里仅记录支付未成功的订单,所以数据量就会很小,那么查询效率就会很高。
另外,掉单表里的记录,不会被永久保存,只是临时性。当支付结果查询成功,或者支付结果明确失败,再或者查询次数到达规定最大次数,就会删除掉单记录。
这就是第八步为什么需要删除掉单表的原因。
如果需要保存每次掉单表查询详情,那么这里建议再新增一张掉单查询记录表,保存每一次的查询记录。
针对这个方案,如果还有其他问题,欢迎留言。
方案优缺点
定时轮询补偿方案,最大的优点可能就是系统架构方案比较简单,比较容易实施。
那么这个方案的缺点主要在于定时任务上。
定时任务轮询方案天然会存在以下不足:
轮询效率稍低
每次查询数据库,已经被执行过记录,仍然会被扫描(补单程序将会根据一定策略决定是否发起支付通道查询),有重复计算的嫌疑
时效性不够好,如果每小时轮询一次,最差的情况下,时间误差会达到1小时
如果为了解决时效性问题,增加定时任务查询效率,那么 1 中查询效率跟 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
抄答案就是了,两套详细的设计方案,解决头疼的支付掉单问题相关推荐
- java掉单_【Java】抄答案就是了,两套详细的设计方案,解决头疼的支付掉单问题...
Hello,大家好,我是楼下小黑哥~ 好久没写支付相关的文章了,今天继续从事老本行~ 上次在文章钱被扣走了,但是订单却未成功!支付掉单异常最全解决方案提到,支付过程会出现掉单.卡单的情况,这种情况对于 ...
- 电大计算机2019作业,【电大题】2019年最新国家开 放大学电大《人文英语2、3、》网络核心课形考网考作业两套汇编附全答案.docx...
[电大题]2019年最新国家开 放大学电大<人文英语2.3.>网络核心课形考网考作业两套汇编附全答案.docx 文档编号:768065 文档页数:61 上传时间: 2019-10-17 文 ...
- 微型计算机原理及应用 考研,中山大学《微型计算机系统原理及应用》考研模拟题两套及答案.pdf...
中山大学<微型计算机系统原理及应用>考研模拟题两套及答案.pdf 考试复习重点资料(最新版)考试复习重点资料(最新版) 封封 面面 第1页 资料见第二页资料见第二页 模拟题一 一.填空题 ...
- python爬虫详细步骤-Python爬虫的两套解析方法和四种爬虫实现过程
对于大多数朋友而言,爬虫绝对是学习 python 的最好的起手和入门方式.因为爬虫思维模式固定,编程模式也相对简单,一般在细节处理上积累一些经验都可以成功入门.本文想针对某一网页对 python 基础 ...
- 一套计算机网络系统设计方案,包含外网、内网、智能化设备网
一套计算机网络系统设计方案,包含外网.内网.智能化设备网. 弱电工程设计的计算机网络系统一般分为三种:内网.外网.设备网,这三种网络系统如何设计?它们的架构是如何的呢? 计算机网络系统就是利用通信设备 ...
- 【杂谈】开学重磅!有三AI最强资料固态硬盘开启预订,3本书视频代码PPT,两套教学视频,所有付费专栏代码+数据...
各位,秋招临近,开学也临近了,有三AI给大家准备了一个带学习资料的固态硬盘,月底发货,喜欢的同学就好好阅读本文了解一下吧. 硬盘产品细节 本次我们的产品为固态移动硬盘,注意是固态硬盘,不是普通U盘,虽 ...
- 由条件熵与无条件熵的关系引出的不等式证明题(不会抄答案系列)
枯燥预警,证明很繁琐,实际上尽力记住公式内涵即可,重点掌握詹森不等式. 选自<信息论(第四版)--基础理论与应用>傅祖芸编著P68,2.15,2.16P68,2.15,2.16P68,2. ...
- 三轴合并_用两套乐高60107合并成铰接式云梯消防车,看看和60112有什么区别
我们之前通过将乐高城市组 60107 那套云梯消防车改装成一个特技赛车冲过终点线的场景,来演示了积木的套内 MOC. 今天我们就来看看两套 60107 又能做什么. 60107 (2006) 2016 ...
- cesium获取模型高度_180套经典夹具设计方案(附详解+模型),原来夹具设计这么简单!...
180套夹具设计方案获取请见文章末尾图片 实际生产当中,很多产品的加工过程都需要有夹具辅助来完成,一套既经济实用又安全可靠的夹具不仅可以大大提高产品的生产质量还可以提高生产效率,工人操作起来也非常舒适 ...
- 计算机二级柏林是第几套,2019年计算机二级Office考试内容及时间安排(内附两套原题库)...
原标题:2019年计算机二级Office考试内容及时间安排(内附两套原题库) 选择题(20分).操作题(80分).考试时长:120分钟 选择题:建议5-10min.Word Excel PPT 各25 ...
最新文章
- Android AudioPolicyService和AudioPolicyManager
- c#_Func和Action委托简介
- 【Linux】解决Linux服务器内存不足问题
- IOS15.0的适配
- C ~ char int 等数据转换问题
- 莫比乌斯反演(bzoj 2301: [HAOI2011]Problem b)
- python---python基本算法的时间复杂度和空间复杂度
- Win10 虚拟机安装 Windows xp(professional sp3)简记(非教学)
- mysql数据恢复(根据.ibd文件恢复数据)
- unity2018关联不到vs_vs2015与unity2018兼容性问题
- HTML5的表单模版
- 电线线缆铜芯和铝芯有什么区别?哪个更好呢?
- 蓝队-Windows操作系统
- 太平洋电脑网左边菜单的实现
- html css基础笔记,学习html/css基础的重点笔记
- 认真的雪歌词的c语言编码,认真的雪歌词
- GAMIT 安装 Make sure the common libraries are curren
- C语言百日刷题第八天
- docker-compose 安装多版本php
- 补充笔记(Linux常用命令+sql表空间,索引,分区,创建用户)
热门文章
- 异步消息的传递-回调机制(转)
- android自定义多按钮点击事件监听事件吗,安卓(Android)动态创建多个按钮并添加监听事件...
- php 盒子边距,CSS 盒子模型外边距
- 拓端tecdat:已迁离北京外来人口的数据画像
- 拓端tecdat|重庆住房租赁市场现状分析:解读出租房市场的数据密码
- linux快捷删除151617文件,mengzhaoliang
- 珍爱网html模板,python爬虫基础实战:爬取珍爱网征婚女士信息,爬取Discuz论坛发帖和回帖代码案例...
- httpd linux启动脚本,Linux下一个智能重启Apache服务器的脚本分享
- CTF入门指南(Capture the flag)
- 【解决】Ubuntu安装NVIDIA驱动(咨询NVIDIA工程师的解决方案)