支付路由系统设计二:核心流程

技术栈:Java+Groovy+Lua+Springboot+Mysql+Redis+Drools+Velocity+RabbitMQ+Spring Data Jpa

目录

一、背景

二、分析

1.命中:

2.优先级:

3.可用性判断:

4.成本计算:

5.权重:

三、讨论:

1. 路由应该每次返回多个支付渠道?

四、总结

一、背景

本篇博文,我们来介绍下支付系统中很重要的一个功能模块--路由系统,当然很多小公司的支付系统可能压根没有这个模块。

先说下路由系统的作用,随着业务不断丰富,支付系统为了满足各种支付场景提供多元化的支付产品,需要对接很多银行、第三方支付机构来为业务方提供服务,随着对接的支付渠道越来越多,支付渠道的管理问题就来了,渠道规则各异,如何从对接的渠道中选择一个可用的、成本最低的支付渠道?当最优通道失败后如何再过滤出次级最优通道重试交易?等等,都是支付路由可做的事。

这次我们先介绍第一个:如何从对接的渠道中选择最优的支付渠道?也就是支付路由系统的核心功能。

在介绍之前,先了解我们的设计背景:

应用架构:

支付路由系统设计二:核心流程_第1张图片

 如上图,简化后的应用架构图(每个应用有各自应用库),可以看到支付路由系统在整个应用中的位置,主要是为PayCore、PayGw提供路由服务。业务线不知道支付系统对接了哪些支付渠道也不必知道,只需要告诉支付系统从XXX账户扣取XX金额的钱(代扣),或者给XXX账户转入XX金额的钱(代发),其余事情就不管了,只要把最终执行结果告诉我就行了。PayCore、PayGw拿到支付指令后也很懵逼,这笔交易应该走哪个支付渠道?于是“询问”路由系统,路由系统根据硬性指标(运营人员配置)和运行时指标(监控系统收集)给出这笔交易应该走哪个支付渠道。

元数据信息:

元数据的关系结构模型,也就是我们的支付渠道,支付渠道支持的交易类型,以及交易类型支持的交易机构(银行)等等,这些是设计路由相关的元数据,其他的响应码映射、机构商户信息等元数据不在此次范围,咱们就暂且忽略。其上三部分信息的关系如图:

支付路由系统设计二:核心流程_第2张图片

表结构关系:

支付路由系统设计二:核心流程_第3张图片

从上图中可以看到这些元数据的层级关系,很好理解,支付系统中很多支付元数据,这些元数据由PayCommon应用维护,每个应用不能随意跨库访问,只能通过库对应的应用接口访问。

每个支付公司各有各自的划分维度,比如将对接的一个支付机构再划分为代扣通道、快捷通道等什么的,我们此处为对接的一个支付机构在我们这里就是一个通道,代扣、快捷仅仅是其下的一种交易类型。

背景就暂时介绍那么多,了解那么多就能展开了...

为了降低阅读难度,阉割掉了很多功能,如运行时指标等。

二、分析

在设计之前,我们首先要了解下路由的基本流程,路由在筛选最优渠道时候主要包括五个部分: 命中+优先级排序+可用性判断+成本计算+权重分流

支付路由系统设计二:核心流程_第4张图片

1.命中 


首先我们搞清楚什么叫命中?以及命中维度?
所谓命中就是交易参数上送到路由系统,触发规则引擎,查找出哪些渠道
“可能”会支持这笔交易,注意这里的可能。打个形象描述吧,这个步骤就是警察拿着目击证人对罪犯的描述信息(报文参数),从一群人中找出符合外貌描述的可疑人,并且这些可疑人天生就有罪犯长相,特别是光头,在后期审问时候头发越少越重点关注,先从发量少的的开始审问(规则优先级);还有的原来蹲过局子,有前科,就算你有一头乌黑亮发,也优于光头先审问,说不准就是惯犯作案呢(强制规则),但是要明白有前科的也不一定是嫌疑人;有的是劳模榜样,国家好青年,则排除(排除规则);取得这些嫌疑人信息后,移交审讯组根据证据确定哪个是罪犯。
命中维度问题,也就是锁定嫌疑人范围问题:

支付路由系统设计二:核心流程_第5张图片
如图:我们现在有这三个维度,支付渠道、交易类型、交易机构 接着上面比喻吧,(支付渠道-某街道 交易类型-某小区 交易机构-某单元)在锁定可疑人时,锁定的维度越小,前期警察叔叔做的摸排工作就越多,体现在系统方面就是运营人在后台配置路由规则做的配置就越多越细,对于系统来说也就越耗性能,此处我们命中维度为交易类型,另外两个维度,一个太泛,一个太细,泛即失去了此环节的意义,太细又加重了此环节运营人员的配置和应用处理效率。

2.优先级

支付路由系统设计二:核心流程_第6张图片
优先级是什么?
继续上例:我们根据发量对嫌疑人进行分组(发量是嫌疑人自有属性,也就是命中的渠道有优先级属性),光头佬组,地中海组,乌黑油亮仔组,但是在进行排序审问前,了解到,其中有一个可疑人员有犯罪前科(强制规则),那么我们就将其优先盘问,同时有一个刚获取到国家好青年表彰,那么我们从可疑人员中剔除,不在我们的排查范围,如果有犯罪前科(强制规则)的可以人员经过审问(可用性判断)就是嫌疑人,那么就直接结案了。

注:很多人这里搞不清楚的一个问题,优先级和可用性问题,笔者公司就是将优先级放到可用性判断规则链里了,结果就是路由经常超时了,原因也很简单,前面不管三七二十一的将命中的支付渠道直接进入可用性判断,花费了很大的力气,结果在优先级这个检验链里排除了,前面费力做的可用性判断没用了,没用了....支付路由系统对设计要求比较高,所以稍有不慎性能就是几十倍的折损。这一块也涉及到我们的系统功能职责,在下面我们单独讨论这块。

支付路由系统作为支付系统里最耗人设计的模块,稍有不慎,性能就大打折扣,性能问题,在设计编码时候就应时刻考虑,而不是仅仅完成功能开发,后期系统响应慢,想改都难了。

3.可用性判断

支付路由系统设计二:核心流程_第7张图片
可用性判断,也就是对命中的渠道进行进一步判断,就像排查可疑人当天夜晚在哪里,在干嘛等等,对应支付路由就是校验此交易类型是否支持此交易的卡行、公私类型、限额、此时是否在此渠道的工作时间等等,大概算下来足有二十项左右。首先进入可用性判断的是有前科的嫌疑人,也就是命中的强制规则,经过多方面盘问,最终两种结果,1.自己确实犯事,2.自己清白,如果是自己确实犯事了,流程结束,退出流程,返回此渠道,不再盘问其余可疑人,如果是清白的则开始盘问其他可疑人。 

在我们盘问其他可疑人员时,根据分组,我们先从光头佬组开始,两个光头依次盘问,也就是从优先级最高的这组开始,如果此优先级所有渠道都没有经过可用性判断处理链,那么接着盘问地中海组可疑人员,如果此组经过可用性处理链后剩余多个渠道,那么流入下一流程,如果只存在一条则直接返回此渠道,如果不存在接着乌黑油亮仔组,这组还是没有则退出流程,无渠道可用。

4.成本计算:


如果同一优先级经过可用性判断后,剩余多条可用通道,那么我们将在此步骤进行成本计算,根据通道成本规则计算。如果流入此步骤有三个渠道,经过计算后成本分别为:支付宝:1元,微信:2元,易宝:1元,那么经过此流程后剩余通道未:支付宝、易宝,将这两个渠道接着流入下一步骤,
如果成本分别为:支付宝:1元,微信:2元,易宝:3元,那么直接返回支付宝渠道。

渠道侧成本规则维护见:支付渠道计价方式管理设计

5.权重:


在上步骤经过计算成本后,同一优先级还剩余多个成本一样的可用通道,那么此步骤将做权重,看这笔交易走哪个通道,权重和优先级都是命中渠道的自有属性,权重就是在配置规则时候一个整形数值:比如到此流程时剩余两个渠道:支付宝权重:30 易宝权重:70,也就是这笔交易30%的概率走支付宝,70%的概率走易宝,以此来做分流。

三、讨论:

1. 支付路由应该每次返回几个支付渠道?

这问题是设计路由时很关键的作用,因为这个问题关系这系统内部流程设计,以及后期的一些业务职责划分。

内部流程设计:返回一个和返回多个上面流程是不一样的,上图流程图为返回一个的流程图,如果返回多个那么就不用进行权重处理了,到成本环节后同一个优先级的逻辑就结束了。

如果是返回多个,那么就要思考一个问题了,业务方什么时候需要多个?无非就是交易重试,如请求第一个支付渠道,如果支付渠道失败了,则重试第二个支付渠道。但是再思考这种情况有多少?如果一天一万笔交易,这种失败的才10笔,那么为了满足这10笔交易的重试,支付路由系统是牺牲9990笔的性能!因为一次返回多条支付渠道业务方使用到的概率很低很低!返回多条支付路由就必须对命中的每条规则都要进行可用性判断,有些可用性判断很费性能的,支付路由费力输出的执行结果到业务方压根就不用,所以在这个方面设计要慎重。

上面我们只是说了一部分原因,返回多条业务方实际压根不用,难道因为业务方实际用的很少就不做了?那肯定不是的,我们需要更好的方式去处理那10笔重试。

业务职责划分:返回多条还是一条还涉及到业务职责的划分,如果一次返回多条,那么什么情况下重试,重试次数,重试超时间,渠道流量分配等一系列的职责就跟路由没关系了,当然你也可以搞出关系了,强掰。

但是想下支付路由系统作为支付系统大脑级别的系统,这些业务职责也应当由路由控制。

所以整体执行流程应该是业务系统在交易时,原来是失败了直接返回业务方失败了,现在是交易失败了,进入重试组件,重新调用路由“询问”要不要重试,如果路由“说”不用重试,则这笔交易才真的失败了,如果路由“说”可以重试下这么几个{AA,BB,CC}渠道,然后会再次请求支付路由,会把此笔交易已经失败渠道集合和告知重试集合都上送,路由侧会在规则交易链里校验命中的支付渠道是不是已经失败了,或者不在重试集合中,可能有点复杂,这也是仅仅一个地方,重试还有交易结果查询的地方,交易结果通知地方,所以要做交易重试属实不容易!这里就不再展开,后面在我们将整个路由设计完成后会接着讨论交易怎么基于路由系统做重试组件切入到原交易流程中达到交易重试的目的。

经过上面的分析,不知道你是否还是坚持路由应该返回多个可用支付渠道,如果还是坚持返回多个那么就给出量化的数据,即一次返回多个支付渠道有多少概率会用到?本篇是坚持返回一个的,因为要重试的场景很少,但是要坚定的是,场景即使很少但是也是支付系统应该具备的功能,属于基础服务了,特别是对于信贷消金行业这个功能很重要,由于支付系统的缺陷没有将应收款回收上来导致用户逾期,是谁的责任呢?如果支付系统没有重试那系统也是个缺陷系统吧。

四、总结

此篇文章我们片了支付路由大概处理逻辑,下篇我们片使用Drools规则引擎+Velovity模板引擎+Groovy实现命中逻辑,也就是支付路由的核心,最近忙着搞论文,更新日期未定~~

你可能感兴趣的:(支付系统设计,支付路由系统设计,rabbitmq,java,分布式)