.Net架构篇:实用中小型公司支付中心设计
前言
说起支付平台,支付宝量级的支付平台和一个小型公司的支付不可同日耳语。一个初创或刚创业一两年的公司,一没人力,二没财力的情况下,如果也想对接支付那怎么办呢?感谢支付宝和微信支付,两大行业巨头提供了简单易用的方案,简化了对接流程,又能支持大部分银行。今天我们就来根据不同业务规模,设计一个能经受业务考验的支付平台。
第一阶段
举个例子,阿力空闲时间,接了个外包的分销系统。业务模型如:成为会员,可以自动带二维码的分销海报,扫描你二维码的人成为会员后,你获得提成。
这个例子有几个核心步骤:
申请会员,支付成为会员,自动生成海报,
计算分销提成。
有点小挑战的自动生成海报。这个可以参考微信参数二维码接口和GDI+绘制图片来搞定,利用html5的canvas也能搞定。
最核心的部分,当然是支付。
先来一张订单表流程图压压场面。
订单模型
前些天看领域驱动提到了核心域和子域,那么整个交易流程是是这个模型的核心域,订单表是交易流程的子域。
我大概说下这些字段,业务类型和业务id以及业务处理url实现了各个业务的解藕,各个业务线都有自己的限界上下文。它可以根据取消日期和取消地址完成订单的取消动作,可以根据支付平台交易id和支付平台查询对账。业务通知状态是用来综述通知业务处理是否成功。说完了订单,让我们来看下整体交易流程。
交易流程
订单有三个主流程,提交订单是用户主动触发,支付回调是属于支付平台触发,定时取消是后台任务根据设定的取消时间自动运行,小业务可以不考虑订单取消问题。
这样来说,第一版支付中心就完成了。由于刚上线,流量每天很少,平稳了运行一段时间后,也许会出现支付平台支付,但搭建的支付中心却未支付,只能手动修改数据库了,并触发业务回调了,这在最终一致性里,可以成为人工补偿。后来不厌其烦,加了个支付日志,记录任何与支付平台交互的信息,然后每隔一段时间扫描最近变更的日志表,并和订单表对比,发现不匹配的,修复为已支付,完美的解决了这个问题,这在最终一致性里,可概括为定时补偿。
交易日志表
老板缺少人手,业务量又上升,又对阿力解决问题的能力很欣赏,就直接把阿力工资翻倍从原公司挖了过来。(故事纯属虚构)
第二阶段
刚过来新公司不久,就接到了一笔融资,然后新公司扩招了很多同事,市场销售人一多,产品线更多,线上支付流量也加快起来。阿力信心满满,觉得很有干劲。得意不久,就遇到了服务线反馈的问题:有客户重复支付,需要退款。于是改订单,清理数据,财务退款,临时解决了问题。后来次数多了,手工处理及易出错,就查询支付宝和微信的自动退款接口,然后依赖日志表记录过支付成功对比判定重复支付,发起退款,引入了自动退款流程。
交易流程补充自动退款流程
然后又接到了一个线上客户需要抢购的需求,每月有一天集中一起抢,类似小米秒杀那样。然后到了激动的那天,系统撑过了三分钟,华丽丽的挂了!熬了二十分钟才恢复正常。
痛定思通,支付中心进入重构优化阶段。由于公司人员扩张,有时间和精力和能力去重购优化更健康的业务架构。
一,引入消息队列Rabbitmq支撑流量削峰。如支付回调先进消息队列,由消息队列去通知业务。大幅度缩短单次请求处理时间,提升并发能力。
二,全面引入Redis缓存,减小数据库访问压力,部分关键业务表启用HttpRuntime缓存,性能指数级提升。
三,引入专业调度工具quartz.net或hangfire。可以用来处理定时查询订单交易问题,及退费问题。
四,购买商业.net监控平台,如听云。检测程序性能。
阿力跟随新公司技术体系,也对支付中心实现了升级。
支付平台回调通知后,先转发到消息队列,由消息队列来通知业务处理,如失败后延时转发到消息队列继续执行,最高重试5次,然后发短信或邮件通知责任人。
针对之前线上支付平台和自建平台不一致问题,利用hangfire调度机制定时每天晚上拉取一周数据和支付平台核对。确保了两个异构系统的一致性。
为防止支付平台同时通知,造成两条支付日志,先更新订单成功后,在队列里,用redis的incr和decr原子性操作,来确保只能同时操作一个订单,另一个通知延迟处理。重复退款时,也要保证同时只能退款一个订单号。(同一时间可以操作不同的订单号,但同一个订单号必须强制避开并发)
数据库开启读写分离,部署集群。
经过阿力和同事们两个月的协力合作与加班加点,新系统终于在那个客户第三次线上抢购前一段时间上线。经过线上抢购验证,新的系统轻轻松松的抗过了抢购,大家一片欢声笑语。阿力看到十几分钟XX百万的交易额惊呆了!,这真是金牌客户啊!
到了年底,微信红包火热起来,许多客户申请开通微信红包,有家客户粉丝有二十多万,发的钱也特别多。当时一到点,十万人齐刷刷摇手机抢红包。最后,重启了几遍应用程序池也不顶用。针对如此的流量,我们应该怎么办呢?每秒万级的请求暂时就不是小公司处理的来的,况且这流量就过年才有,像级了春运。人有那么多,抢到红包的人是有限的。百分之九十五的人都是无效流量。那就取巧吧,随机抽取一部分人的数据进入服务器,其他的人就本地留存吧,通过这种思路减少了一大部分流量。
只考虑第一,第二阶段的话,上面关于支付中心的思考架构是完全可以满足交易量的。况且又有多少公司能迈向独角兽之路呢?
念天地之悠悠,独怆然而泪下!
第三阶段
上面那种方式虽然取巧,针对特定业务,本来就是抢红包,大部分人都是无效的,能说的过去,假如是主业务流程有万级每秒甚至百万千万级每秒的请求量应该怎么办呢?阿力陷入了迷茫。
听说过docker,kuberneters为代表的容器编排,听说过CI/CD自动部署,听说过微服务的强大,听说过负载均衡,仿佛都是方向。
大海跨不过陆地,台风却能轻易穿梭,大化为小,繁化为简,聚简成面,规模化微服务也许才是解决巨量请求之道!(故事纯属虚构,不要代号入座)
附录:最终一致性
说完了解决中小型流量的问题,我们来了解下一致性问题。
1、关系型数据库事务追求ACID:
A: Atomicity,原子性
C: Consistency,一致性
I: Isolation,隔离性
D: Durability,持久性
2、CAP(帽子理论)
C:Consistency,一致性, 数据一致更新,所有数据变动都是同步的
A:Availability,可用性, 好的响应性能,完全的可用性指的是在任何故障模型下,服务都会在有限的时间处理响应
P:Partition tolerance,分区容错性,可靠性
帽子理论证明,任何分布式系统只可同时满足二点,没法三者兼顾
3、Base模型:
BA:Basically Available,基本可用
S:Soft State,软状态,状态可以有一段时间不同步
E:Eventually Consistent,最终一致,最终数据是一致的就可以了,而不是时时保持强一致
利用查询模式,补偿模式,异步确保模式,定时校对模式等可实现分布式系统最终一致性。
最终一致性更详细用法参考李艳鹏老师关于分布式一致性的讲解。https://www.jianshu.com/p/1156151e20c8?from=singlemessage&isappinstalled=0
后言
阿力解决了支付中心的稳定问题后,就买了许多书,看到了上面关于最终一致性的陈述时,心里想到,这些都是我已经实现了的,原来还有这么多头头道道??
阿力又看到了领域驱动设计等书,感慨:支付领域模型真是学习领域驱动设计的最好实践。它具有独立的限界上下文,通过回调url和其他业务限界上下文沟通。
最后再用交易流程在做个总结吧!
交易流程
关键点:
1.回调部分,有消息队列通知,并支持失败重试。
2.每天晚上定时拉取支付平台对象记录核账,保证最终一致性。
3.支付平台回调时,根据支付日志判定是否重复支付,重复支付的发起自动退款。
源码
计划用.netcore按领域驱动的方式,完成以上设计。日期未定。
声明
全文除附录部分最终一致性外,均为原创。如文章能给你带来帮助,请点下推荐,感谢支持。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
为什么我们要坚持写博客?
前言 从2018年7月份,我开始了写作博客之路。开始之前,我打算分享下之前的经历。去年初公司来了个架构师,内部分享过docker原理,TDD单元测试驱动,并发并行异步编程等内容,让我着实惊呆了,因为确实是干货。从那以后我买了快十本书了,为了补充我的基础知识,我觉得我对工作上的上层应用是足够完成工作了,但是沉淀到底层,沉淀到分布式,沉淀到大前端,我的知识栈脆弱的经不起推敲。计算机是一门高速发展的学科,跟不上时代就会被淘汰。没有背景的人唯一出路就是努力向前! 收获 线程安全集合类 在我7月份的一篇akka.net提到一个业务场景,就是异构系统数据同步,之前采用的是任何更新都直接推送队列,这无疑是很消耗性能的。我当时想到了加锁存httpruntime cache,定时推送。在研究了olreans的connect源码后,发现了大量的基于多线程的集合类,可以替代我之前的想法。就在昨天测试zipkintracer是又看到了那些多线程安全的集合。我就知道以后任何推送数据都可以采用这种方式,然后再异步落库。 关注到园区大牛 不断的坚持写了三个月博客后,部分文章也引起了一些关注,如《.net外国高质量博...
- 下一篇
数据中心内的负载均衡-MPTCP
1. 为什么用MPTCP做负载均衡? (1)充分利用网络资源 以手机为例,手机包含两种上网方式,蜂窝移动数据网络(2G,3G,4G)和WIFI网络。我们希望在有WIFI的时候尽量使用WIFI,这样可以节省成本,没有WIFI的时候自动切换到蜂窝移动网络,避免断连。同样在PC端,我们希望有线网卡和无线网卡可以同时上网,提高网速。但是使用TCP协议是无法实现上述功能的。 (2)提供可靠传输 MPTCP在协议栈中,位于TCP之上,利用建立TCP子流进行数据传输。TCP是面向连接的4层协议,它可以提供可靠传输,并且拥有拥塞控制机制。但是TCP的单路径传输的协议,即便网络上存在多条路径资源,也无法利用这些路径资源。因为TCP是通过四元组:{源IP,目的IP,源端口,目的端口} 唯一的确定一个连接,当四元组中的任一项发生变化时,会导致连接中断。因为应用程序使用TCP协议只能和单个四元组绑定,无法同时使用多个IP。使用MPTCP正好可以解决这个问题。 数据中心存在大量的路径资源,使用MPTCP可以更加充分地利用带宽资源,且提供可靠传输。数据中心最常使用的负载均衡算法为ECMP,通过根据数据流的五元组哈...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS6,CentOS7官方镜像安装Oracle11G
- Linux系统CentOS6、CentOS7手动修改IP地址
- MySQL8.0.19开启GTID主从同步CentOS8
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS8安装Docker,最新的服务器搭配容器使用