多业务线亿级体量,携程是怎么做账务中台的(2)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 多业务线亿级体量,携程是怎么做账务中台的

3、系统设计


1) 基础组件设计


  • 日志组件


我们日志进行logger输出,会碰到以下的痛点:

1)我们经常会对方法的入参,出参及异常进行日志打印,还要把tag写入clog和ES,手写的话工作量巨大。2)有些日志需要脱敏处理,比如手机号、身份证号、卡号,不能把明文输出到日志。3)logger目前只支持抛公司的logger日志平台,部门想自定义日志查询分析工具比较困难。

所以在设计统一账务中台化的工程中,进行了日志组件的设计:

1)统一使用高性能的log4j2替代logback;2)通过spring aop和annotation,支持方法入参、出参、异常日志的自动打印;3)支持clog和es的tag的配置,可以从参数中获取,并通过log4j2的ThreadContext

打入本地线程,线程使用过程中tag共享,代码如下所示:

4)支持配置脱敏规则,进行敏感信息的脱敏处理;5)同步抛公司的clog和cat,异步抛kafka,异步接受程序进行ETL处理,抛部门自己的日志系统(比如鹰眼系统,hive日志分析系统);6)抛kafka时,对于原始报文进行apache arvo压缩处理,减少传输带宽;7)支持原生API,可以手工打tag和脱敏处理。       流程图如下:

  • 分库分表组件


分库组件,我们调研过公司现有的和开源的组件,最终选用了开源的sharding-jdbc。

1)携程的dal组件

dal使用dal cluster通过服务端配置分库分表信息,但是全套使用dal太过笨重,它是一个完全的ORM框架,生成sql的工具不支持生成特殊自定义的sql。

2)去哪儿的qdb组件

通过配置表达式或算法的方式进行分库分表配置,缺点是文档较少,容易踩坑。

3)MYCAT

Mycat是一个中间件,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。Mycat的缺点就是需要搭建一套中间件做拦截者,而且需要自运维,成本比较高。

4)sharding-jdbc

当当网首先推出的开源分库组件,现在变成apache项目,分为sharding-jdbc、sharding-proxy。开源社区活跃。我们使用轻量级的sharding-jdbc,可以编写算法,支持精确分片、范围分片、复合分片和自定义hint分片,配置方式支持xml、yml和java api方式。基本能解决我们所有的分库分表需求。我们把分库算法包成jar包,方便使用。配置我们使用yml。在使用过程中,需要结合dal cluster的key,代码示例如下:

2) 前置系统设计

账务前置位于整个账务体系的最上游,提供标准的交易接口,包括入款、入款返还、出款、出款返还、预授权类、转账以及批量接口。

  • 标准的交易接口


整合之前的老系统,都是业务导向的接口,随着业务的不断迭代,接口越来越多,职责不清晰,代码重复,给维护带来很大的工作量。比如:光提现接口,就分为个人提现、返现提现、商户提现和定向提现。另外,原先的子账户的交易顺序是硬编码的,如果发生子账户的增加或交易顺序的变化,带来的复杂度就成倍增加。

我们经过研究,发现账务处理是有共性的,对于交易顺序、原子交易类型都是可以提取出属性的。所以我们建立了场景码模型。

首先,我们定义子账户id,按账户类型+币种+业务类型唯一定义一个子账户。

其次,按产品代码+交易类型来定义一个交易顺序,交易顺序关联子账户id,该顺序设置为默认的场景码。接口只要传入产品代码和交易类型就能能走默认的场景码。

第三,支持商户自定义场景码,我们维护了一个后台管理系统,允许商户自定义场景码,审核通过后,接口传入该场景码编号就可以走自己定义的场景码。


  • 异步化


我们接口都是同步接口,为了减少同步响应时间,把次要的工作通过mq进行异步化处理。比如:转账的转入方入款,抛送会计等。


  • 数据库策略


除了支持自己的支付业务,也支持把账务系统输出到其他BU。为了数据权限及互不影响,我们做了数据隔离。需要特别说明的是,只做数据隔离,系统还用同一套,不做隔离,方便发布和运维。数据隔离分两层,第一层是domain,区分自有/BU。第二层是具体分库。

sharding库也分两套,Mapping库和交易库。Mapping库存放请求流水号和前置流水号的关系。交易库存放所有的交易信息。特别地,我们把逆向交易和原交易落在同一DB中,这样有利于控制逆交易和原交易在一个事物内。

首先,我们使用请求流水号做hash算法,分散到mapping db。Mapping db只保存请求流水号和前置流水号的关系,Mapping db也是分库的,分库数量初始是固定的,以后扩展可以用一致性hash算法进行扩容。


我们的交易表是通过权重配置来分库,通过权重可以进行数据的自由分配。DB支持友好的扩容,下线和故障切换。我们有一套故障切换的方案,如果某个分片出现dbconnect异常,我们会抛送支付的监控系统。监控系统会有套智能算法会实时监控,达到阀值后自动触发该分片的markdown/markup机制。


  • 异常处理


高并发场景下的异常处理一直都是各方研究的课题。为了适应高并发场景,前置做了如下的异常处理:

1)幂等机制:所有接口都支持幂等操作。2)重试机制:接口内部调用的重试,job补偿重试,上游也可以发起相同请求报文的失败重试。3)查询机制:所有接口都写了一套查询接口,上游可通过查询接口查该交易的最终状态。4)通知机制:支持成功/失败的结果主动通知上游的机制。


3)原子系统设计




原子系统流程处理中,主要有以下几步:订单参数预处理,分单,同步执行器,异步执行器,后处理,最后封装参数返回。为方便业务扩展,系统维护,在分单和执行部分,系统架构采用责任链模式的分单器;代理进行分单,产生drivers,再由系统自动注册的同步执行器和异步执行器进行执行。目前,只有订单登记簿采用异步方式完成,后续job系统中会对任务进行相应的补偿。

下图为原子系统的系统架构图:

PreBizProcess是参数预处理部分根据调用域不同进行了定制化校验与信息构造。

DispatcerControl是分单部分,因为原子系统负责账户余额的管理,不存在任何业务逻辑,所以可以将记账模型进行抽象以适应不同的业务需求。记账模型包括账户入账与出账(Accnt)、活动入账与出账(Activity)、资金冻结与解冻(Fund)、日登记簿入账与出账(DaliyBook)、订单登记入账与出账(OrderBook)等记账模型。针对有效期概念的账户,增加了登记簿管理,日登记簿对账户同一有效期的资金进行汇总,订单登记簿是有效期的资金的订单维度的记录。

SynExecutor是同步执行器主要负责出账入账,资金冻结解冻,日登记簿处理;AsynExecutor是异步执行器负责订单登记簿的记账操作。日登记簿采用同步执行的方式,而日登记簿记账成功可保证订单登记簿记账成功,故订单登记簿采用异步记账既可以保证记账成功又能减少系统同步处理的时间。

后处理部分会发送动账消息,给关心账户余额变动的系统,比如风控。

4)会计系统设计


会计系统采用复式记账方式完成,可以清晰的表述资金是从哪里来并流向了哪里,针对不同的业务涉及不同的清分规则。在清分规则中可以配置记账的不同策略,比如单条、汇总记账等不同策略。

针对同一业务多科目的场景,添加扩展配置,实现清分规则的科目动态化。


5)日终系统设计


  • 为什么需要日终系统


1)提供账务系统支撑

要保证账务系统能正常运转,账务的余额要100%准确。影响账务系统稳定性的主要因素有以下几个方面:

  • 缓冲记账,问题表现:分录有数据,明细无数据
  • 会计异步记账,问题表现:明细有数据,分录无数据
  • 分录规则配置,问题表现:同一笔分录中,借贷方金额不一致


2)为企业大财务提供汇总记账凭证

账务系统记录的是业务账,这些数据是整个企业财务数据的一部分,需要合并到公司的大财务系统中去。

日终系统对会计分录进行加工映射为大财务的分录,然后汇总,直接对接企业ERP总账。


  • 日终系统都做了什么


image.png

1)生成快照

每日凌晨统计截至上一日的所有账户的快照。

2)生成分户账

根据快照生成分户账。

3)生成总账

根据分录流水生成科目总账,科目发生额和余额从末级科目逐级汇总到一级科目。

4)总账平衡检查

余额平衡检查:一级借方科目余额=一级贷方科目余额;发生额平衡检查:一级科目借方发生额=一级科目贷方发生额

5)总分核对

总账科目余额等于分户账科目余额。业务24小时不间断运行,账户中余额在不断变化,无法准确取到期末的账户余额进行核对,采用余额快照与总账科目余额进行核对。

6)稽核明细

检查明细账与分录流水是否一致。对于当日发生过余额变动的账户,昨日余额与分录流水中的发生额进行轧差,检查计算出的余额与快照余额是否一致。


  • 日终系统遇到的挑战


1)24小时记账

在银行账务系统中,对于24小时运行,有很多种方案,例如切换余额、记不同分户账、日切后补流水等,但无论哪种方案,都不能实现完全24小时运行。

其问题,主要是因为日终要进行总分核对,而分户账余额是在不断变化的,所以要想办法把期末的分户账余额取出来进行核对。

本日终系统解决方案,采用余额快照与总账进行核对,这样即使分户账余额进行变化,也不影响总分核对。

2)生成账户快照


生成快照的方式有两种:

  • 从账户余额中获取
  • 交易明细按账户汇总发生额更新快照


相较于数亿账户而言,每日发生交易的则要少得多。采用动账汇总的方式,对于数据库的操作更少,处理时间更快。

3)流程复杂、测试困难

对日终任务模型进行抽象,按照业务边界划分为:快照生成、分户账生成、总账生成等多个子任务,自动注册到任务工厂中,以便编排调用。


4)总结


此系统业务接入规则、会计清分规则都是基于配置的,在业务发展的新增账户类型、业务、币种、机构等日常变化都可以基于配置进行。          

   

03


   后记

账务中台建设到现在,已经完成了携程体系内账务中台的基本建设,这只是中台建设的第一步,后续规划还包括分布式事务、热点账户的处理;新机构业务接入如何更简洁等等。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
5月前
|
新零售 人工智能 供应链
推三返一新零售模式系统开发|成熟案例|方案设计
新零售是指通过互联网技术和大数据分析,将线上线下商业模式相结合
|
NoSQL 算法 Java
千万级订单生成的痛点与架构
千万级订单生成的痛点与架构
177 0
|
存储 数据采集 缓存
数据中台建设:千万级的瀑布式,和十万级的迭代式,你会选择哪一个?
连接1次孤岛,服务N个场景。Tapdata Live Data Platform (LDP)通过为实时数据集成增加一个高速缓存的方式,将企业核心的常用的数据实时复制到缓存层(最后一次ETL),再从缓存层为企业的多个应用场景快速提供数据, 实现一次打通,多次复用的降本增效价值。Tapdata LDP 现已入驻阿里云云市场。
16117 0
|
消息中间件 缓存 运维
多业务线亿级体量,携程是怎么做账务中台的(1)
多业务线亿级体量,携程是怎么做账务中台的
216 0
|
消息中间件 XML 缓存
美团点评智能支付核心交易系统的可用性实践(上)
背景 每个系统都有它最核心的指标。比如在收单领域:进件系统第一重要的是保证入件准确,第二重要的是保证上单效率。清结算系统第一重要的是保证准确打款,第二重要的是保证及时打款。我们负责的系统是美团点评智能支付的核心链路,承担着智能支付100%的流量,内部习惯称为核心交易。因为涉及美团点评所有线下交易商家、用户之间的资金流转,对于核心交易来说:第一重要的是稳定性,第二重要的还是稳定性。
美团点评智能支付核心交易系统的可用性实践(上)
|
监控 算法 安全
美团点评智能支付核心交易系统的可用性实践(下)
背景 每个系统都有它最核心的指标。比如在收单领域:进件系统第一重要的是保证入件准确,第二重要的是保证上单效率。清结算系统第一重要的是保证准确打款,第二重要的是保证及时打款。我们负责的系统是美团点评智能支付的核心链路,承担着智能支付100%的流量,内部习惯称为核心交易。因为涉及美团点评所有线下交易商家、用户之间的资金流转,对于核心交易来说:第一重要的是稳定性,第二重要的还是稳定性。
美团点评智能支付核心交易系统的可用性实践(下)
|
XML 数据可视化 IDE
小记基于xstate实现携程金服业务流程动态化
小记基于xstate实现携程金服业务流程动态化
512 0
小记基于xstate实现携程金服业务流程动态化
|
新零售 数据可视化 数据挖掘
解决方案应用实例 |“业务+数据”双中台,阿里云推进正佳广场精细化运营
正佳广场作为中国商业的典型,尝试各种创新的发展,借助阿里云打造以“业务+数据”双中台为核心的新运营模式。
2256 0
解决方案应用实例 |“业务+数据”双中台,阿里云推进正佳广场精细化运营
|
人工智能 Cloud Native 搜索推荐
直面最大挑战双11 阿里数据中台为商家带来确定性保障
2020双11将成为史上最具科技含量的一届双11,数据中台则是确定性的创新增长引擎。
7595 0
直面最大挑战双11 阿里数据中台为商家带来确定性保障
|
存储 Cloud Native 关系型数据库
支撑数千家天猫商家CRM业务,数云高弹性数据库如何做
我们可以看到在云时代的大背景下,企业选择数据库存储产品需要综合考虑性能、稳定性、成本等不同方面,都是企业客户考虑的重点。同时云原生数据库在高并发、高可用、高可靠以及可扩展性方面的优势也再次被证明。
830 0
支撑数千家天猫商家CRM业务,数云高弹性数据库如何做