大家好,又见面了,我是你们的朋友全栈君。
目录
前言
支付系统的作用
核心流程
架构图
代码流程
线程池中处理发送消息到MQ、持久化的数据库
支付成功后,消息分发流程图
订单作为消费者消费消息
测试
文章中的图片和在摘录不是来自一篇文章,所以细节不是完全对应。可借鉴的是开发的思路:
前两点是业务需求,后两点是功能实现。
https://www.cnblogs.com/veblen/p/10992167.html
http://www.woshipm.com/pd/1392102.html
订单支付:
用户支付完订单后,需要获取订单的支付信息,包括支付流水号、支付时间等。支付完订单接着就是等商家发货,但在发货过程中,根据平台业务模式的不同,可能会涉及到订单的拆分。
跟着标注的序号,可以跟踪到一个支付请求是如何发起的(Sequence Diagram就免了),流程描述如下:
让我们更深入一点,我们来看三张Class Diagram:
① 先说说支付任务(PayTask)部分。PayTask和Payment两个都是MongoDB中的Document对象,但在任务执行期间,PayTask是用Redis进行缓存的,方便客户端随时发起Query,任务执行成功后,会生成Payment对象,最终PayTask和Payment都会持久化到MongoDB中。在PayService中,有对支付任务的一些基本操作,包括任务提交,取消,重试,构建等等。
② 再说说任务的执行(runner)。这部分和RabbitMQ紧密相关,一旦一个支付任务形成了,就会放入任务执行队列中,由消费者取出执行。在TaskRunner中,有两个基本的接口方法:run(task)、retry(task),分别是执行任务和重试任务。在AbstractPayTaskRunner中已经封装好了这两个方法,继承AbstractPayTaskRunner需要实现doTask方法,从返回值可以看出,这个过程是异步化的。关于Retry机制,用户可以设置重试与否,一旦设置了TaskInfo.needRetry=true(不出意外,默认就是允许重试),就启用了Retry机制。还可以设置重试的次数(TaskInfo.retryTimes),默认三次,分别间隔1s,2s,3s,间隔时间以公差为1的等差数列组成。当然不会让用户无限重试,系统内置有一个最大重试次数,最大重试次数内置为5次。
为什么是5次?
你感受一下,1s,2s,3s,4s,5s,整个请求链条就被拉长到了15s,这对客户端简直就是灾难了!!
创建支付
订单作为消费者消费消息
在测试程序中调用sendMessage
因为发送消息是在线程池中,当测试程序(主程序)停止运行,线程池也就停止运行,所以,为了让主程序不停止,在方法末尾加上:System.in.read();
System.in.read()可以实现输入字符,返回字符的Unicode码,但是缺点是只能输入一个字符 System.in.read() 返回的是输入数值的 ASKII 码(一个 int 整数)。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/134795.html原文链接:https://javaforall.cn