查看原文
其他

微服务与领域抽象:支付系统2.0架构演进

技术琐话 2021-08-08

Editor's Note

【变化】中的【不变】,是抽象核心领域模型和平台化架构的关键。电商支付系统十年来,最核心的领域并没有变化,这就是领域建模的魅力所在。

The following article is from 中生代技术 Author 手哥


本文节选自手哥架构宝典 - 支付系统演进2.0版本


手哥架构宝典之支付系统1.0发布后,很多架构师朋友表示受益匪浅,询问支付系统2.0版本什么时候放出来,今天刊发出《架构宝典》支付系统2.0版本,以飨读者

概述


1.0 的支付系统中,我们遇到了诸多问题。痛定思痛,我们决心对支付系统做一次架构升级。那么,怎么去做支付系统的架构升级呢?我们从两个方面来进行架构升级梳理:
  • 巨大的单体应用必须要拆分,在拆分之前,需要确定业务、系统边界,并对支付业务进行建模。
  • 构建完整的资金核算体系,以能够清晰地知晓各类业务的流水、收入、支出等。 

  • 支付系统 2.0 - 拆分系统边界


拆分单体应用之前,从三个维度对边界进行拆分:
  • 基于业务,拆分为面向支付业务和面向资金核算两套体系。
  • 基于场景,例如依据支付流程等进行拆分。
  • 基于技术实现,例如出于对系统的性能等考虑拆分。 

我们将支付系统中的核心系统拆分为收银台、交易核心、支付核心、渠道网关、账务系统、会计系统、清算系统、合规系统等。
如图 14.4 所示的是核心支付链路流程示意图。 


得益于蘑菇街强大的基础平台及中间件系统,比如 RPC 服务框架 Tesla、数据库中间 件 Raptor、可靠的消息中间件 Corgi、数据库事件变更中间件 Pigeon、数据配置推送平台Metabase 及分布式缓存 KVStore 等,我们在 2015 年第四个季度对支付系统做了整体的服务化拆分,拆分后的架构如图 14.5 所示。


下面大致介绍一下各系统的功能:



  • 面向支付业务,可拆分为收银台、交易核心、支付核心、渠道网关。
  • 面向资金核算,可拆分为会计系统、账务系统、清算系统、合规系统。
  • 其他基础服务的拆分,比如支付会员服务、支付风控和对账系统等。

支付系统 2.0详解



以上讲述了支付系统 2.0 的整体架构,接下来对各个核心系统的拆分和实现进行具体介绍。

2.1


交易核心

从刚才的支付链路中可以看出,交易核心作为支付系统入口,对接上层的业务系统。在 2015 年年底,支付系统有着数十张支付交易表,如何抽取合适的业务模型是最重要的事情。另外,为了数据的统一性,我们对分散的数十张支付交易表进行了多表聚合,以及订单关联。同时,支付的接入管控也放在了交易核心中实现,整体架构如图 14.6 所示。


2.1.1


基础交易类型抽象

在交易核心中做基础交易类型的模型抽象,主要基于对支付的理解。如图 14.7 所示, 电商交易的预售和广告营销的 CPC(Cost Per Click 的缩写,每次点击付费广告)购买都是用户直接购买并支付给收款方,那么我们可以将该行为抽象为即时交易,即从 a 用户到 b 用户的直接支付行为。


基于对业务的分析和理解,我们对交易核心的业务进行了抽象,抽象为 10 多种交易类型:


  • 比较熟悉的交易类型:担保交易、即时交易、充值、提现、担保退款、即时退款、转账等。
  • 不太常见的交易类型:提现退票、退款退单、异常退款、充值退款等。


2.1.2


多表聚合及订单关联

对数十张支付交易表进行多表聚合是基于一张主表来实现的。而在这种情况下,业务订单如何保持唯一是我们需要考虑的事情。考虑到需要对上层业务保持极少的侵入性,在新设计的支付交易表中有专门的字段用于做唯一键约束:业务识别码+业务订单号


另外,做一个小功能,使任何订单都可以追溯到初始订单,如图 14.8 所示,担保交易下的所有单子都可以找到,同时也能追溯到初始订单。


2.1.3


支付管控

鉴于交易核心为支付平台的入口,针对 1.x 支付系统中支付接入无授权问题,我们也在交易核心里面做了支付接入的管控 —— 授权和鉴权。
为任何一个接入支付的业务分配唯一的业务标识码及授权的 Token。从而使得业务在支付接入时,需要带上 Token 和加盐过的加密数据。

2.2


支付核心

我们将 1.0 支付系统中的支付模块切分为两层——交易核心和支付核心。交易核心面向 上游业务,支付核心面向支付系统内部。


支付核心整体架构如图14.9所示,

我们对支付核心同样进行了支付类型的抽象:充值、提现、退款、转账,任何一个交易核心订单请求都能由这 4 种基础支付类型组合进而完成支付行为。


另外,支付核心需要基于系统、用户指令等完成各种各样的支付行为。按照简单的做法,我们可以在不同的分支上实现各种支付行为,但是这样可能会导致支付行为耦合,并使支付逻辑判断变得复杂。基于这种原因,我们对支付工具进行组件化拆分,封装为数十种支付工具,通过支付编排来执行支付行为。

2.2.1


支付编排

支付交易订单通过支付规则生成具体的支付请求(即支付核心记录),支付请求通过支付指令编排规则获取一组支付工具包,通过支付执行器完成对支付工具的调用执行。


这样的封装使我们可以实现插件式开发,以及支付规则可配置化,继而让支付核心内部的支付工具互不影响并系统地简化。整个编排过程如图 14.10 所示。

2.2.2


异常处理机制

支付核心有一个比较重要的功能,即如何对支付异常进行处理——支付过程中的重复支付、部分支付、金额不一致、全额退款等异常都需要做异常退款处理。


如图 14.11 所示,以部分支付为例,我们做了一个异常管理组件来处理这种异常,在 “红包支付+优惠券支付+网关支付”组合支付中对每次的支付都进行上报,通过异常管理组件对部分支付成功的行为进行反向异常退款。


(小编:从上图,能否思考背后的分布式事务模型?)

2.3


渠道网关

我们对渠道网关系统进行拆分,渠道网关接受来自支付核心的支付请求,并与第三方支付进行交互。渠道网关同样抽象了基础服务类型:支付、退款、提现、签约、查询等。同时,出于性能方面的考虑,将网关系统切分为两个子系统——网关核心和网关前置:
  • 网关核心负责渠道路由、渠道订单的管理及渠道分组。

  • 网关前置负责渠道适配、报文转换及外部通信。 



渠道网关系统的整体架构如图 14.12 所示。


2.4


资金核算体系

资金核算体系主要由会计系统、账务系统、清算系统和合规系统组成,整体架构如图14.13 所示。


  • 会计系统: 对业务运转信息进行管理、核查、披露,展现资金的来龙去脉。

  • 账务系统: 由支付核心驱动,记录管理账户信息,直接反映用户的账户余额和资金变更明细。

  • 清算系统: 由支付核心驱动,实现机构间资金关系应收应付的主被动清算及资金划拨。

  • 合规系统: 基于支付数据,向资金监管方同步交易信息流和资金流,从而契合央行的合规监管要求。

截至目前,我们对支付系统中面向业务的体系及资金核算体系进行了介绍。

统一平台业务上下文


1.0 支付系统单体应用通过确定系统边界、业务建模拆分之后,整个支付平台被拆分为几十个服务,那么如何保障业务信息在服务间流转而不丢失是我们需要考虑的问题,就好比如何让各个系统交互时都讲普通话,而不是讲方言。针对这个问题,我们在平台中做了统一上下文的要素信息(唯一业务标识码),使其在整个支付平台链路中全程传递,具体要素如下。


  • 商户: 诸如蘑菇街电商交易、美丽说电商交易等。
    订单类型: 基于交易核心的业务类型,诸如担保交易、即时交易、转账、提现等。

  • 订单场景: 诸如电商预售、营销广告购买等。
    支付机构: 诸如支付宝、微信等。

通过统一平台业务上下文,我们能够在任何一个系统中清晰地看出是哪种业务,在哪种场景下,使用哪个渠道做了什么事情。



往期推荐


技术琐话 


以分布式设计、架构、体系思想为基础,兼论研发相关的点点滴滴,不限于代码、质量体系和研发管理。本号由坐馆老司机技术团队维护。



    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存