zoukankan      html  css  js  c++  java
  • 支付渠道路由系统进化史

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

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

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

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

    初期

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

    系统设计图如下:

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

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

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

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

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

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

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

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

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

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

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

    中期

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

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

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

    相关实现如下:

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

    渠道系统提供服务:

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

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

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

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

    这个设计的问题在于:

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

    借助 Dubbo API

    后期

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

    官方文档建议:

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

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

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

    总结

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

  • 相关阅读:
    Leetcode 238. Product of Array Except Self
    Leetcode 103. Binary Tree Zigzag Level Order Traversal
    Leetcode 290. Word Pattern
    Leetcode 205. Isomorphic Strings
    Leetcode 107. Binary Tree Level Order Traversal II
    Leetcode 102. Binary Tree Level Order Traversal
    三目运算符
    简单判断案例— 分支结构的应用
    用switch判断月份的练习
    java基本打印练习《我行我素购物系统》
  • 原文地址:https://www.cnblogs.com/goodAndyxublog/p/10848843.html
Copyright © 2011-2022 走看看