对账是典型的批量处理任务,需要批量调度平台进行调度。对于比较复杂的调度逻辑(比如依赖关系调度、灵活触发、运营界面等),需要高可用、高并发、高伸缩的分布式调度系统,可以考虑用Zeus、Quarts、Elastic-Job、Azkaban等进行定制化开发。
下面重点介绍一下明细对账以及技术实现方案。
(图4 明细对账总体流程)
明细对账的总体流程如图4所示,包括对账文件下载、文件预处理、轧账、平帐,以及运营平台对平帐过程的监控、预警,下面进行详细介绍。
对账文件下载
对账文件一般由对账对手方根据数据库的交易记录产生,并放置和对账方约定的地方,比如文件服务器、FTP服务器等。对账方根据事先约定的方式,获取对账文件,比如通过HTTP/HTTPS下载或者FTP/SFTP拉取。
对账预处理
为了安全性、客户保密性、防篡改,会对对账文件进行加密处理,常用的有3DES、AES等对称加密或者RSA非对称加密,以及MD5、SHA1、SHA512等摘要信息,还有各种签名机制。
获取到对账文件后,并不能立即进行对账,需要首先按特定安全机制进行解密,另外也需要把对账文件格式转换成内部系统方便处理的格式。这些都是轧账前的预处理。
轧帐
(图5 代收交易轧帐示意图)
轧帐是会计科目流程之一,定期或者企业需要时,核对总账与明细账,每日记账是否一致。轧帐是对账最核心的流程,用来确认双方或多方的账目是否一致,不一致的情况下,有哪些差错。
轧帐的正确与否,影响到后续的差错处理即平帐。以向用户代收为例,轧帐的流程如图5所示。
为了确认交易记录的标准,需要双方约定,哪个或者哪些要素可以唯一确定一笔交易,比如订单号,有时也会加上时间。
在具体对账的内容上,一般只需比对金额即可,某些情况下为了完备性,还会校对清算日、客户信息等其他明细数据。
某些非金额因素会影响到佣金计算、多方分润等,所以也需要进行轧账确认。
技术是为商业目标服务,业务发展到什么规模,就有什么样的技术与之匹配。所以,对账系统没有标准完美的技术解决方案,不同的业务场景会有不同的特性需求。
尽管行业、业务规模不同导致技术方案有一定的差异性,但是差异是相对的,其中还有很多共性。下面所讨论的轧账技术方案是较通用的,当然还有很多技术细节,不展开讨论。
依次读取预处理后的对账文件,根据交易标识在数据库中找出对应的记录,进行比对,检查是否一致。
此种轧帐的方式非常简单,容易理解,程序实现也比较简单。缺点也显而易见,支持数据量少,如果交易量大,会导致内存不足,并且大量数据库查询,会耗尽数据库资源,对联机交易有影响。
另外,因为是串行处理,在交易量大时,会大大延长轧帐时间,影响正常业务的进行。
改进措施
将对账文件按一定规则划分为小文件,确保每次只处理记录数有限的文件;
按对账文件的记录数进行划分,由不同的节点进行处理,比如1-n由节点1处理,(n+1)-2n由节点2处理,(i-1)n+1-i*n由节点i处理,…充分利用分布式系统进行处理;
为了减少对联机交易的影响,可以在日切之后将交易记录导入到专门的对账库或者历史库进行对账;
在数据库中,新增和对账文件结构一致的对账表,将预处理后的对账文件按记录逐条导入到对账表中。利用数据库提供的join, left join,right join, case when等SQL语法进行轧帐。
比如SQL:select case when a.amt<>b.amt then 1 else 0 end from a join b on a.order_no=b.order_no,可以把金额不一致的找出来。
select case when a.amt is null then 1 else 0 end from a join b on a.order_no=b.order_no,可以把本地系统中不存在的交易的找出来。其他以此类推,不一一介绍。
这种轧帐逻辑放在数据库,简单方便,后续方便扩展;对账对手方的数据都存储在数据库,可以非常容易可视化和排查问题。
缺点是:交易量大时,导入量大,数据预热慢,数据库性能很容易成为瓶颈;所有的计算节点集中于数据库,无法利用分布式。
改进措施
批量导入数据库;
根据轧帐标识进行分表分库处理,并进行汇总。