前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >支付渠道路由系统进化史

支付渠道路由系统进化史

作者头像
andyxh
发布2019-09-10 19:33:17
9950
发布2019-09-10 19:33:17
举报
文章被收录于专栏:程序通事程序通事

支付系统一般需要对接多个支付渠道,一是为了保证系统的可靠性,不能因为单一渠道的问题影响整个支付系统。二是为了提高支付能力,不同渠道提供支付能力不同。三是为了降低支付成本。

对接多个支付渠道以后,为了可以正确选择支付渠道支付,因此设计渠道路由系统。

155755816925615e8c95361d34e2e8dcec3ede1e4751a.png
155755816925615e8c95361d34e2e8dcec3ede1e4751a.png

从上图可以看到路由系统功能其实很简单,分发支付请求到正确的渠道。但就是这个简单系统,也经过几次系统改造升级,最终才成为现在的样子。下面就来说说这个系统是如何演进。

下面假设对接支付渠道为支付宝与微信。

初期

支付系统初期,这个阶段业务需求较简单,仅仅需要满足一个支付场景(例如使用支付宝支付)。为了快速上线,设计方案就简单粗暴,对外直接暴露支付服务接口,由业务系统发起直接调用。

系统设计图如下:

1557558195734f56b2af2598348c0b7026a7b7f538c37.png
1557558195734f56b2af2598348c0b7026a7b7f538c37.png

这个阶段由于只有一个支付渠道,所以也不需要有路由系统,直接由业务系统调用支付服务接口发起支付。

这个设计方案存在很多问题:

  1. 业务系统与支付系统位于同一个系统,系统任何一次变更都会影响整个系统。
  2. 扩展性问题。接入新支付渠道,如微信,需要新暴露一个微信支付服务接口。业务系统需要改动代码。从另一方面讲,业务系统承担路由系统的功能。
  3. 复用性。新支付渠道,其实除了与支付渠道交互相关代码之外,其他代码可以复用。

针对以上问题,将系统进行了相应改造。

首先是将支付系统与业务系统单独拆分出来,成为两套单独的系统。支付系统对外暴露一组通用接口。业务系统仅对接这组接口。业务系统若想指定支付渠道支付,接口参数传入渠道标识即可。这样就将耦合在业务系统中路由功下沉到支付系统。

其次梳理渠道接口文档,抽象出共性接口。接入新支付渠道,只要继承接口,实现相关方法即可,简化渠道开发难度。

改版后的系统实现图如下:

15575582396465806ad80c2f5414bb635b0dfd150f44a.png
15575582396465806ad80c2f5414bb635b0dfd150f44a.png

此时,路由系统知识支付系统的一个模块,具体实现如下。

首先定义通用渠道接口,其中 channelName 方法,返回渠道渠道唯一标识,如支付宝渠道返回 aliPay

1557558264457c6bac4bb077f4dadb1978bb33345983e.png
1557558264457c6bac4bb077f4dadb1978bb33345983e.png

然后根据 Spring ApplicationContext getBeansOfType 方法,获取实现同一个接口的所有 Bean.最后将其放入 Map 缓存中,其中键值为 channelName 方法返回渠道标识。

15575582782446a64cce2d48147bfa55fec4061adfd2c.png
15575582782446a64cce2d48147bfa55fec4061adfd2c.png

这个阶段方案的问题在于支付系统所有模块位于同一工程。有些模块需要频繁发布,而有些模块,如渠道模块,路由模块改动就很少。这样就导致系统任一改动发布,影响整个支付系统可用性。

中期

针对初期后面的问题,进行了相应改造。

首先还是进行拆分,将支付系统按照模块拆分。路由系统,渠道系统,成为独立系统,独立部署维护。

1557558294307e5e382cd8cb54a159143ebd8642f0d8a.png
1557558294307e5e382cd8cb54a159143ebd8642f0d8a.png

系统之间调用采用 RPC 通讯,使用 Dubbo 框架。

相关实现如下:

相关接口逻辑不变,只是将同一进程内调用变成跨系统的调用。

渠道系统提供服务:

155755831008441c9b01adc0e45c7bd8c5baa053bcc27.png
155755831008441c9b01adc0e45c7bd8c5baa053bcc27.png

这里改动,将渠道标识放入 Dubbo 服务 group 字段,借助 Dubbo 分组功能标识中唯一的渠道系统。

路由系统引用渠道系统的服务:

1557558332575d80f014cc6b5423a817c18189be97d6b.png
1557558332575d80f014cc6b5423a817c18189be97d6b.png

这里同样需要设置 group 且需要和服务提供者一致。然后在路由系统中将服务注册到缓存中,使用渠道标识为 key,渠道服务名为 value。

1557558342097e514538a992140648ee5723d45a3f29a.png
1557558342097e514538a992140648ee5723d45a3f29a.png

最后路由系统借助 Spring ApplicationContext getBean 获取具体的服务。

15575583555300b6c9d0d5311475b8592d0c014a54922.png
15575583555300b6c9d0d5311475b8592d0c014a54922.png

这个设计的问题在于:

路由系统中需要手动引用渠道系统服务,然后再注册。这样在增加渠道系统就比较繁琐。那是不是可以做到增加渠道系统时,无需修改路由系统,路由系统自动发现服务?

借助 Dubbo API

后期

查看 Dubbo 文档,可以直接使用 ReferenceConfig 直接查找服务提供者。

1557558370850a844af4a344a4704b7d8732ede9a0041.png
1557558370850a844af4a344a4704b7d8732ede9a0041.png

官方文档建议:

ReferenceConfig 实例很重,封装了与注册中心的连接以及与提供者的连接,需要缓存。否则重复生成 ReferenceConfig 可能造成性能问题并且会有内存和连接泄漏。在 API 方式编程时,容易忽略此问题。

这里使用ReferenceConfigCache,用于缓存 ReferenceConfig 实例。

去除之前所有引用服务配置文件以及缓存注册代码,引入 ReferenceConfigCache,改造如下。

15575584076432a4bb2e3c49145d3a93eb6c86f8b352e.png
15575584076432a4bb2e3c49145d3a93eb6c86f8b352e.png

总结

回顾上文路由系统,可以看到初期没有路由系统,整个系统可以运行下去。但是随着系统复杂度提高,初期系统架构已经不能满足系统的高效运行,所以才一步步改进系统。改进的过程中,不断发现方案不足处,然后一步步迭代演进。这个过程中,要善于利用现有框架的功能,加速功能的开发。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-05-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初期
  • 中期
  • 后期
  • 总结
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档