Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >干货 | 多业务线亿级体量,携程是怎么做账务中台的

干货 | 多业务线亿级体量,携程是怎么做账务中台的

作者头像
携程技术
发布于 2021-04-09 02:37:40
发布于 2021-04-09 02:37:40
1.3K0
举报
文章被收录于专栏:携程技术携程技术

作者简介

本文为联合撰文,作者团队负责携程集团支付账务系统、消费金融账务系统、清结算和对账等工作的的开发、设计和运维工作。

一、前言

原先携程内部的各账务系统都是随着自身的业务发展而建立起来的,其中有些共同的东西,但也存在着不少差异。但其对底层业务的抽象是统一的,都可以抽象为:账户开立、记账、稽核。为了系统开发、运维的简便性,也为了更好的为前台业务提供支持,我们计划实施账务中台系统,从而做到账务系统的:

1)敏捷:快速的适应业务需求的变化,满足外部快速变化的需求,实现业务的敏捷。

2)解耦:建立功能独立的系统,避免因为一个功能的修改而影响很多方面,降低功能的耦合度。

3)复用:对一些公共组件的复用,提高开发效率,避免重复建设,使得数据和流程都可以得到管控。

二、账务中台之路-基础篇

2.1 系统概述

2.1.1 背景

账务系统从2014年开始一期建设,先后经历了两次大的技术架构升级。

一期:

账务组刚成立的时候,携程的JAVA技术栈尚未完善。

技术上我们是首批试点使用JAVA的小组,使用的分布式RPC框架是Zeroc ICE,它可以支持多语言,通过slice文件生成代码,性能也比较好,所以当初选型用了这个。消息队列用的RABBITMQ,缓存用的REDIS。这些集群都是自运维的。

业务上,一期的业务只支持单用户单账户的模式,交易支持充值、支付、退款、预授权类(预授权冻结,预授权撤销,预授权完成,预授权完成撤销)、提现、转账,接口都是基于业务接口独自开发的。

系统业务架构图如下:

二期:

随着携程JAVA技术栈的完善,二期主要针对JAVA技术栈进行了升级,放弃了自运维的集群,使用了携程JAVA体系,包括SOA,qconfig,qmq,qshecdule等技术。业务上增加了会计系统和日终的实现。

系统业务架构图如下:

原有的账务核心系统存在以下问题:

1)抽象不足:对业务规则抽象不够,如果新增业务需要编码实现

2)隔离不够:系统不同业务的系统流量、数据没有隔离,存在某一业务有问题,影响全局的风险

3)降级策略:不支持

4)扩容困难

基于以上问题,我们设计并实现了新的统一账务平台。

2.1.2 目标

针对旧系统的不足,我们确定统一账务平台的目标:

1)抽象

2)隔离

3)易扩容

4)配置化

5)支持多机构多币种

2.2 系统架构与简介

统一账务系统旨在建立一套立足于携程集团之下的高可用,易扩展,业务可定制的账务系统。系统包括场景码系统,账务前置系统,账务核心系统,账户管理系统,会计系统,异步系统,job系统,日志系统。各个系统之间通过dubbo进行服务拆分解耦。

系统业务架构图如下:

  • 前置系统:账务的业务处理系统,主要负责对上游业务系统的对接,完整账户的拆分等工作。
  • 账务核心系统(原子系统):主要负责账户记账,记录对商户、用户、内部户等客户账的动账及明细。
  • 管理系统:对外提供商户、用户、内部户的管理服务,包括创建、查询、状态冻结、状态解冻等服务。
  • 会计系统:采用复式记账法根据分录规则对发生的交易进行记录,来表示资金的流转。
  • 基础服务系统:对外提供科目、分录、交易码等基础配置的查询服务。
  • 日终系统:对记账原子和会计系统数据进行稽核,完成数据校验工作。

2.3 系统设计

2.3.1 基础组件设计

2.3.1.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和脱敏处理。

流程图如下:

2.3.1.2 分库分表组件

分库组件,我们调研过公司现有的和开源的组件,最终选用了开源的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.3.2 前置系统设计

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

2.3.2.1 标准的交易接口

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

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

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

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

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

2.3.2.2 异步化

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

2.3.2.3 数据库策略

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

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

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

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

2.3.2.4 异常处理

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

1)幂等机制:所有接口都支持幂等操作。

2)重试机制:接口内部调用的重试,job补偿重试,上游也可以发起相同请求报文的失败重试。

3)查询机制:所有接口都写了一套查询接口,上游可通过查询接口查该交易的最终状态。

4)通知机制:支持成功/失败的结果主动通知上游的机制。

2.3.3 原子系统设计

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

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

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

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

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

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

2.3.4 会计系统设计

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

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

2.3.5 日终系统设计

2.3.5.1 为什么需要日终系统

1)提供账务系统支撑

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

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

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

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

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

2.3.5.2 日终系统都做了什么

1)生成快照

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

2)生成分户账

根据快照生成分户账。

3)生成总账

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

4)总账平衡检查

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

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

5)总分核对

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

6)稽核明细

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

2.3.5.3 日终系统遇到的挑战

1)24小时记账

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

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

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

2)生成账户快照

生成快照的方式有两种:

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

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

3)流程复杂、测试困难

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

2.4 总结

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

三、后记

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 携程技术中心 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【支付系统设计从0到1】支付宝架构中记账功能设计分析
支付宝架构的PPT中对记账部分的说明,分内外账户,如图所示。那么支付宝系统为什么要采用如此设计呢?
金融民工小曾
2018/09/14
2K0
【支付系统设计从0到1】支付宝架构中记账功能设计分析
解密:站在资金的视角看支付(上)
提起在线支付,大家一定不陌生,这个行业发展了快20年了,最近又推出了“碰一碰”支付,而且随着微信和淘宝破冰,京东和支付宝和解,整个支付生态一定会更加开放。但绝大多数人对支付的了解应该只是浮在水面上的冰山一角,做为支付行业从业者,今天来带大家看看冰山下面的部分:欢迎走进“资金管理”这个神秘领域。
Louis XIV
2025/02/19
660
解密:站在资金的视角看支付(上)
老焦专栏 | 为什么需要用业务补偿服务和TCC 型服务实现数据一致性
分布式事务解决的问题很明确,就是在服务分布在不同进程、数据分布在不同数据库时,如何解决数据一致性问题。对于这个问题,业界的共识是不要启用数据库 XA 模式,因为分布式情况下,如果启用了 XA 事务,必然会有数据库锁存在,实际上造成了两个服务之间的耦合,与分布式服务的初衷背离,还不如部署在一起。在不使用 XA 的情况下,经常使用业务补偿和TCC(Try/Confirm/Cancel)模式的服务来解决:为什么有这样两种模式呢,他们有什么区别,各自适合什么样的场景,这两种模式是否带来了代码开发的复杂度?经常有人问我这样的问题,这里简单说明一下:
yuanyi928
2019/05/31
1.1K0
支付系统中,账户体系的设计与记账处理
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/03/04
2.3K0
图解:支付系统产品架构
关于产品架构和业务架构的区别,一直存在争议。由于产品架构没有固定的标准,许多产品架构借鉴了TOGAF的4A架构理论中的业务架构方法。如果非要区分技术和产品,可以这样理解:产品主要关注用户使用的功能和内在关系的展示,而技术则更侧重于功能实现和技术栈的支持。
Louis XIV
2025/01/16
1690
图解:支付系统产品架构
聚合支付的对账体系设计
对账具有普遍性,已经被应用在金融支付、消费金融、小额贷款、电商零售、现金管理、油卡充值、批量缴税、POS刷卡、ATM业务、外卖平台、酒店预订等场景中。
我只是会一点编程
2022/04/01
1.4K0
腾讯财付通会计核算系统原理与架构
作者:shuangchen,腾讯 FiT 线后台开发工程师 财付通作为业界领先的第三方支付公司,一直致力于为互联网用户和各类企业提供安全便捷的在线支付服务,本文将介绍财付通如何通过会计核算系统来保障财付通亿万资金安全。 1. 背景 1.1. 财付通资金账务系统介绍 1.1.1. 账户体系 财付通作为业界领先的第三方支付公司,一直致力于为互联网用户和各类企业提供安全便捷的在线支付服务。财付通为用户或商户创建支付账户,用于承载用户或商户资金余额以及余额变动情况。财付通资金账务系统中,按账户属性分为现金账户、交易
腾讯技术工程官方号
2022/12/29
3.7K0
腾讯财付通会计核算系统原理与架构
互金账户系统如何应对高并发、热点账户等问题
互联网金融系统的核心是支付结算,而支付结算的基础又是账户系统。互金账户系统的特点是并发量大、响应快、交易金额大,热点账户问题突出。一个合格的账户系统既要解决上述问题,又必须绝对保证资金安全。作为宜信这家互联网金融公司的支付结算中心,其账户系统也必须具备上述特征。
宜信技术学院
2019/06/28
6.1K0
【支付系统设计从0到1】支付系统账户体系设计(上)
在银行、支付公司以及电商平台的支付系统中,如果不是只做交易转发,而是真正需要做账务处理清结算,一定会涉及到账户体系的设计,一套好的账户体系应该是与业务无关的。账户体系在银行叫核心系统,在支付公司或者电商平台都是虚拟账户体系。在这一篇里我们主要讲讲支付系统的账户体系的产品设计,在下一篇里重点介绍技术设计中需要考虑的问题。
金融民工小曾
2018/09/14
3K0
【支付系统设计从0到1】支付系统账户体系设计(上)
互联网账户系统如何设计(下篇)?
在上一篇文章中我们通过场景举例的方式,讨论了一套相对通用的互联网业务账户系统,从业务模型上应该如何定义。那么除了从业务模型上进行定义外,在具体系统实现上又该如何设计?又有哪些需要注意的地方呢?在本篇内容中小码农就和大家一起讨论下账户系统的实现细节,希望可以和大家一起交流进步。
用户5927304
2019/07/31
2.3K0
资金视角看支付系统架构设计
在线支付是一个有近 20 年发展历程的行业,其背后系统的技术设计也随着时间、政策、技术的迭代,不断发生着变化。作为一个与钱直接打交道的行业,支付系统的准确性、安全性、稳定性要求都非常高,对程序员而言无疑是一个非常有挑战性的技术领域。 本文从资金的视角提炼了支付系统背后的业务与技术要点,帮助大家理清支付和资金的关系,文中多处架构示意图非常直观,相信能给大家一些全面的技术输入!
腾讯云开发者
2024/12/11
3320
资金视角看支付系统架构设计
图解大厂清结算系统设计
账务系统为外部客户和内部管理者提供符合公司内部财务核算的各种会计凭证、账簿与财务报表,一般分为:
JavaEdge
2024/05/26
6130
图解大厂清结算系统设计
你小子可真刑,居然想篡改微信余额?
小帅:你不就是做微信支付的?改一个余额很简单吧?用你们技术的话说,余额就是数据库里的一个值,一条SQL就能搞定。
Louis XIV
2025/01/07
5691
你小子可真刑,居然想篡改微信余额?
财务系统需求分析 用户分析 功能需求
本文档为财务管理软件系统的需求文档。首先简单介绍了有关会计的相关知识,以及会计在处理账务时的流程和一些列操作,然后着重介绍了为实现会计办公无纸化而设计的管理软件,分析了该系统应该具备的功能,并对每一个功能模块的具体功能做了详细的介绍。
爱明依
2019/03/12
4.7K0
支付系统
支付系统是连接消费者、商家(或平台)和金融机构的桥梁,管理支付数据,调用第三方支付平台接口,记录支付信息(对应订单号,支付金额等),金额对账等功能,根据不同公司对于支付业务的定位不同大概有几个阶段:第一阶段:支付作为一个(封闭)的、独立的应用系统,为各系统提供支付功能支持。一般来说,这个系统仅限于为公司内部的业务提供支付支持,并且和业务紧密耦合。第二阶段:支付作为一个开发的系统,为公司内外部系统、各种业务提供支付服务,支付服务本身应该是和具体的业务解耦合。
纯洁的微笑
2018/12/21
2.9K1
支付系统
【干货】完整的支付系统整体架构!
  从产品分类、模块功能和业务流程,了解支付产品服务的设计。 支付产品模块是按照支付场景来为业务方提供支付服务。这个模块一般位于支付网关之后,支付渠道之前。 它根据支付能力将不同的支付渠道封装成统一的接口,通过支付网关来对外提供服务。所以,从微服务的角度来说,支付产品本身也是一个代理模式的微服务,它透过支付网关响应业务方请求, 进行一些统一处理后,分发到不同的支付渠道去执行,最后将执行结果做处理后,通过支付网关再回传给业务方。支付产品在支付系统架构图中的位置,如下图所示: 产品分类   在不同的公
Java技术栈
2018/03/30
11.6K1
【干货】完整的支付系统整体架构!
支付的新视角,资金业务应该怎么玩?
提起在线支付,大家一定不陌生,毕竟这个行业发展了快20年了。但绝大多数人对支付的了解应该只是浮在水面上的冰山一角,做为支付行业从业者,今天来带大家看看冰山下面的部分:欢迎走进“资金管理”这个神秘领域。
Louis XIV
2024/12/30
1460
支付的新视角,资金业务应该怎么玩?
【支付系统设计从0到1】支付系统账户体系设计(下)
在上一篇里我们主要讲了支付系统的账户体系的产品设计,在这一篇里重点介绍技术设计上需要考虑的一些问题。
金融民工小曾
2018/09/14
1.7K0
【支付系统设计从0到1】支付系统账户体系设计(下)
论篡改微信余额的技术可刑性
应该不只我一个人这么想过吧?如果能修改微信/银行卡余额就好了? 抛开……不谈,如果真要这么干,技术上我们有什么可行思路呢? 本文是鹅厂资深资金架构师分享的技术步骤,其实也不难,只要 5 步就刑了。
腾讯云开发者
2025/01/09
3611
论篡改微信余额的技术可刑性
支付系统设计:支付系统的账户模型
账户体系设计首先要区分两个概念,支付账户和登录账号。 这是两个不同业务领域的概念:支付账户指用户在支付系统中用于交易的资金所有者权益的凭证;登录账号 指用户在系统中的登录的凭证和个人信息。 一个用户可以有多个登录账户,一个登录账户可以有多个支付账户,比如零钱账户,储值卡账户等。 一般来说,支付账户不会在多个登录账户之间共用。如果没有特殊说明,下文中的账户,都默认指支付账户。
纯洁的微笑
2018/12/24
3K0
支付系统设计:支付系统的账户模型
推荐阅读
相关推荐
【支付系统设计从0到1】支付宝架构中记账功能设计分析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文