那最近正在接手现在的对账系统,由于当前系统日均数量都在千万级,所以对账系统架构与之前架构完全不一样。
那就这个话题,聊聊如何实现千万级数据支付的对账系统。
什么是对账?我们先来回顾下什么是对账?
也许你对对账这个概念比较模糊,但是这个场景你肯定碰到过。
上班路上买了一个煎饼,加了根里脊与王中王,然后你扫了老板的二维码付了 10 元钱。
你跟老板说你已经付了 10 元钱,老板看了下手机,果然有一条 10 元支付记录,老板确认收到钱,然后就把煎饼给你。
这个过程,你说你付了 10 元,老板确认收到 10 元,这就是一只简单的对账过程。
回到我们支付场景,用户下单使用微信支付 100 元购买了一个狗头抱枕,这时我们这边会生成一条支付记录,同时微信支付也会生成记录。
那微信第二天就会生成一个账单记录,我们拿到之后把我们的交易记录跟微信记录逐笔核对,这就是支付对账。
为什么需要对账?正常支付的情况下,两边(我们/第三方支付渠道)都会产生交易数据,那支付对账过程,两边数据一致,大家各自安好,不用处理什么。
但是有些异常情况下,可能由于网络问题,导致两边数据存在不一致的情况,支付对账就可以主动发现这些交易。
对账可以说支付系统最后一道安全防线,通过对账我们可及时的对之前支付进行纠错,避免订单差错越积越多,最后财务盘点变成一笔糊涂账。
支付对账系统开篇先来一张图,先来看下整体对账系统架构图:
整个对账系统分为两个模块
对账模块
差错模块
对账模块,主要负责对账文件拉取,数据解析,数据核对,数据汇总等任务。
差错模块是对账模块后置任务,对账模块核对过程产生无法核对成功的数据,这类数据件将会推送给差错系统。
差错系统将会根据规则生成差错订单,运营人员可以在后台处理这列数据。
今天这篇文章先不聊具体的系统设计,先来回顾下之前的对账系统设计,简单了解下对账的整体流程。
对账系统设计对账系统如果从流程上来讲,其实非常简单,引用一下之前文章流程图:
https://studyidea.cn/articles/2019/08/26/1566790305561.html
整体流程可以简单分为三个模块:
本端数据处理
对端数据处理
本端数据与渠道端数据核对
本端数据指的是我们应用产生的支付记录,这里根据账期(交易日期)与渠道编号获取单一渠道的所有支付记录。
对端数据指的是第三方支付渠道支付记录,一般通过下载对账文件获取。
由于每个渠道下载方式,文件格式都不太一样,对端数据处理的时候需要将其转化统一数据格式,标准化在入库存储。
网上找了一份通用账单,可以参考:
对端数据转化存储之后,对账流程中,对端数据也需要跟本端数据一样,获取当前账期下所有记录。
两端数据都获取成功之后,接下来就是本地数据逐笔核对。
核对流程可以参考之前写的流程:
上面流程其实也比较简单,翻译一下:
查找本端数据/对端数据,然后转化存储到 Map 中,其中 key 为订单号,value 为本端/对端订单对象。
然后遍历本端数据 Map 对象,依次去对端数据 Map查找。如果能查找到,说明对端数据也有这笔。这笔核对成功,对端数据集中移除这笔。
如果查找不到,说明这笔数据为差异数据,它在本端存在,对端不存在 ,将其移动到差异数据集中。
最后,本端数据遍历结束,如果对端数据集还存在数据,那就证明这些数据也是差异数据,他们在对端存在,本端不存在 ,将其也移动到差异数据集中。
PS:上述流程存在瑕疵,只能核对出两边订单互有缺失的流程 ,但是实际情况下还会碰到两边订单都存在,但是订单金额却不一样的差异数据。这种情况有可能发现在系统 Bug,比如渠道端上送金额单位为元,但是实际上送金额单位为分,这就导致对账两端金额不一致。
之前对账系统日均处理的支付数据峰值在几十万,所以上面的流程没什么问题,还可以抗住,正常处理。
但是目前的支付数据日均在千万级,如果还是用这种方式对账,当前系统可能会直接崩了。。。
千万数据级带来的挑战第一个,查询效率。
本端/对端数据通过分页查询业务数据表获取当天所有的数据。随着每天支付数据累计,业务表中数据将会越来越多,这就会导致数据查询变慢。
实际过程我们发现,单个渠道数据量很大的情况下,对账完成需要一两个小时。