写点什么

宜信支付结算账户系统浅析

2020 年 2 月 12 日

宜信支付结算账户系统浅析

互联网金融系统的核心是支付结算,而支付结算的基础又是账户系统。互金账户系统的特点是并发量大、响应快、交易金额大,热点账户问题突出。一个合格的账户系统既要解决上述问题,又必须绝对保证资金安全。作为宜信这家互联网金融公司的支付结算中心,其账户系统也具备上述特征。


一、 账户体系


1. 账户结构


宜信支付结算账户体系是客户、用户、账户三层结构,证件号和证件类型唯一确定一个客户,客户号和机构号确定一个用户,一个用户下可开多个不同类型的账户。如图:


1545043406776090395.png


2. 账户属性


账户系统的基础是账户,所有的操作都围绕着账户进行,账户包含以下一些属性:


1545043425710059979.png


  • 会计科目:每个账户金额的变动要体现一些会计的属性,以便会计核算。

  • 账户类别:分为个人账户、企业账户、平台类账户。

  • 账户明细:账户的明细是反应账户余额变动的每笔详情,采用复式记账法,包含本对方账号、账户等信息、借贷方向、摘要、借贷方的发生额及余额等信息。

  • 账户余额:记录账户的实时余额。


3. 会计科目


账户下挂在最底层的会计科目下,会计科目决定了账户的含义及余额变动方向。会计科目的一些属性如下:


1545043456062038767.png


  • 科目类别:资产类、负债类、所有者权益、成本类、损益类等。

  • 科目级别:会计科目的级别,一级科目、二级科目、三级科目等。下级科目归属上级科目。

  • 余额方向:标示余额是在借方还是贷方。

  • 科目的期末余额:每日日切后会汇总底层科目所有下挂账户在上一会计日的余额总和,上级科目汇总下级科目的余额总和。


4. 科目树


宜信支付结算账户系统采用科目树的概念,每个机构都会绑定一个科目树。科目树的根节点是一级科目,底层的科目下挂账户,结构如下:


1545043481657004111.png


二、 账户系统架构


宜信支付结算账户系统采用公司自研的分布式微服务框架,对外暴露 http json 接口,内部各服务间采用 redis 实现的消息队列通讯。


1. 账户系统功能架构


宜信支付结算账户系统分为接入模块、记账子系统、开户子系统、异步记账模块、查询子系统、定时任务子系统、日终子系统、异步日志模块,下图是账务系统功能模块图:


1545043508256032871.png


  • 接入模块:提供报文解析、验签、参数校验、权限认证等公共服务,是账户系统的统一入口。

  • 异步日志模块:异步记录业务系统请求报文。

  • 记账子系统:账户系统的核心模块,处理业务系统的记账请求。

  • 开户子系统:处理业务系统的开户请求。

  • 首次开立账户:为个人或企业开立客户、用户及提前配置的默认开通的账户。

  • 指定开立账户:个人或企业在首次开立账户后,可按科目号指定开立账户。

  • 查询子系统:提供账户、记账的一些查询功能。

  • 异步记账模块:提供异步记录账户流水的功能。

  • 定时任务子系统:处理失败重试、热点账户等的定时任务。

  • 日终子系统:提供日切以及日终跑批的功能。


1) 记账处理


记账处理是账户系统的核心功能,该功能对性能的要求比较高,高并发下热点账户问题比较突出,资金的正确性也必须保证,并且根据业务不同,记账的分录也是五花八门,宜信支付结算账户系统如何应对这些问题,这里重点介绍下:


  • 账户系统记账采用记账服务的概念,每个记账服务就是一个记账分录的模板,业务系统按照这个模板传入记账金额、账户号或者用户号等信息。

  • 账户系统采用 redis 分布式锁,防止业务系统重复提交请求。设置记账订单防重表,按照请求单号和机构号对记账请求做幂等性校验。

  • 采用复式记账法,按照会计规则按照借贷记录流水,有借必有贷。

  • 记账处理时,更新账户余额后同步返回结果给业务系统,异步的处理记账流水。同时设置补偿机制,定时重试记账流水处理失败的订单,重试三次失败后报警人工介入。

  • 记账规则处理,每个记账服务可以绑定一些记账规则,账户系统根据记账服务遍历其绑定的规则,顺序处理。


2) 热点账户问题


热点账户问题是账户系统的痛点,也困扰了我们很久,这里着重说下。


– 充值时的记账分录是,


借方:三方支付待清算账户(+)


贷方:个人余额账户(+)


当大量用户充值时,三方支付的待清算账户就是热点账户,频繁的增加余额。


–提现时的记账分录是,


借方:个人余额账户(-)


贷方:三方支付资产账户(-)


当大量用户提现时,三方支付的资产账户就是热点账户,频繁的减少余额。


–P2p 业务收服务费的记账分录是,


借方:个人 p2p 账户(-)


贷方:商户服务费账户(+)


当大量向用户收取服务费时,商户服务费账户就是热点账户,会频繁增加余额。


–p2p 业务服务费付款的记账分录是,


借方:商户服务费账户(-)


贷方:个人 p2p 账户(+)


当大量用服务费余额向用户付款时,商户服务费账户就是热点账户,会频繁减少余额。


记账时,所有涉及的账户余额都要做 update 更新,高并发情况下,当出现上述类型的热点账户时,由于数据库的行级锁,对同一账户的更新余额操作由并行变成串行,单个请求的响应时间变长,从而拖垮整个记账服务。


宜信支付结算账户系统针对上述问题做了如下处理:


我们把热点账户按照金额变动方向分为加频账户(余额增加频繁)、减频账户(余额扣减频繁)、双频账户(余额增加扣减均频繁)。


【加频账户处理】:准实时更新余额。先将金额变动插入临时表中,由定时任务按照一定频率汇总发生额,并更新账户余额,而后删除临时记录。当加频账户减钱余额不足时,主动去汇总发生额。这里需要考虑主动汇总发生额和定时任务处理的并发情况,我们在该定时任务执行时设置 redis 锁,防止并发,主动汇总时会去判断这个 redis 锁是否存在,如存在证明定时任务正在执行,无需主动汇总,可能是真的余额不足。主动汇总同样会设置 redis 锁,定时任务同样会判断。


【减频账户处理】:将减频账户拆分多个子账户,减频子账户设置金额报警,如果某个减频子账户余额不足触发报警,会对该子账户做资金归集,将其他子账户余额归集到该子账户(每个子账户设置可归集金额限制)。如在交易过程中发现该子账户余额不足,转向使用其他子账户记账。由于拆分子账户,余额查询时需要汇总各个子账户余额返回;记录主账户流水需要记账后余额,这里需要异步计算汇总。当减频账户加钱时,需要平均分配入账到不通的子账户。


双频账户处理】:将双频账户拆分多个子账户。加钱时,准实时更新余额,先将子账户金额变动插入临时表中,由定时任务按一定频率汇总发生额,将汇总的发生额更新进对应的子账户,并删除金额变动记录;减钱按照之前减频账户的逻辑执行。


3)记账死锁问题


高并发情况下,当多个账户之前互相转账时,可能会出现死锁问题。


例如:A 余额账户 —> B 余额账户(线程 1) 和 B 余额账户—>A 余额账户(线程 2) 两个转账请求并发,账户系统对每个转账请求都会更新 A、B 余额,这两个更新需要在一个事务里,正常流程线程 1 先更新 A,再更新 B,线程 2 先更新 B,再更新 A,线程 1 更新完 A 后会等待 B 的锁,不提交事务,线程 2 更新完 B 后会等待 A 的锁,不提交事务,这样两个线程互相等待锁,造成死锁。


宜信支付结算账户系统针对这种情况提出了解决办法,对账户号进行排序后再更新余额,这样每个线程都是先更新 A 再更新 B,解决了死锁问题。


2. 账户系统存储层架构


宜信支付结算账户系统数据库采用 Mysql,缓存采用 redis。


  • Mysql 数据库采用主从架构,一主二从,主库向从库同步数据。针对一些数据量大的表进行分表,比较有代表性的是账户流水表,既要按账户维度查询,又要按时间维度汇总,所以针对这个特点,冗余了一张表,一张按照账户分表,一张按照日期分表。

  • Redis 采取集群架构,集群中每个点主备的形式。


3. 账户系统的网络层架构


账户系统各个服务部署在同一机房,其中记账子系统和异步记账模块部署在 4 个不同的物理机上,其他子系统和模块部署在 2 个不同物理机上。最前端采用 nginx 实现负载均衡。


本文转载自宜信技术学院网站。


原文链接:http://college.creditease.cn/detail/198


2020 年 2 月 12 日 15:27713

评论

发布
暂无评论
发现更多内容

极光开发者周刊【No.0702】

极光开发者

架构实战营模块一作业

王晓宇

架构实战营

来一份全面的面试宝典练练手,看这篇足矣了!

欢喜学安卓

android 程序员 面试 移动开发

币安智能合约Dapp系统开发技术

薇電13O25249123

区块链 智能合约

【零基础】讲述网络安全介绍,想要学网安的小伙伴赶紧的

H

网络安全 计算机网络 网络

别再往收藏夹怼资源了,收好这个视频创作导航网站就够了。

彭宏豪95

效率 视频 导航网站 视频制作

《啊哈C语言!》学习笔记(1)

Nydia

当我给小姐姐讲述为何黑客要挟制路由器DNS 该怎样实时发觉和防备的方法后,小姐姐那崇拜的眼神令我无法忘却

H

网络安全 计算机网络 网络

5分钟速读之Rust权威指南(三十五)状态模式

码生笔谈

rust

以太坊的 ChainId 与 NetworkId

看见月亮的人

区块链 以太坊 ChainId NetworkId

秋招提前批开始了,一文带你了解,C++ 后台开发知识点及学习路线

奔着腾讯去

程序员 面试题 学习路线 校园招聘 秋招

区块链3.0的到来又能为我们带来哪些便捷呢?

IPFS8822

区块链+ FIL挖矿步骤 ipfs怎么投资?

垃圾回收器的前世今生

中原银行

垃圾回收

2021最新一线大厂Java高级架构师面试题总结

云流

Java 程序员 架构 面试

分布式磁盘 KV 存储 - Kvrocks

kvrocks

RocksDB redis cluster Redis 协议 storage KV存储引擎

IPFS挖矿算力排行榜?IPFS挖矿排行榜?

IPFS老胡

字节三面终上岸,这份热腾腾的面经,赠与有缘人!!!

喝酸奶不舔盖

被裁程序员面试的心路历程,4 轮拿下字节 Offer,面试题复盘(附答案)

喝酸奶不舔盖

为什么你总是买了很多不需要的东西?

石云升

消费者 7月日更

神仙级Springboot笔记!每一步操作和代码都有,绝了

喝酸奶不舔盖

【LeetCode】从前序与中序遍历序列构造二叉树Java题解

HQ数字卡

算法 LeetCode 7月日更

第一模块作业

晨晨

架构实战营

网络安全对现在乃至以后,对人们的安全有着重大的保障

H

网络安全 计算机网络 网络

GitHub霸榜月余的24万字Java面试手册,竟是阿里机密

Java 白

Java java面试

这份485页32W字Java面试手册,让众多粉丝直通阿里!

Java架构师

Java 程序员 面试 阿里

每天学习10个实用Javascript代码片段(一)

devpoint

JavaScript LocalStorage 7月日更

字节、美团面试后,熬夜总结出大厂常问面试真题及解析

菜菜山

Java 编程 程序员 架构 面试

辩证|北鲲云和你一起探讨关于生命科学发展的意义

北鲲云

Spring Boot 无侵入式 实现RESTful API接口统一JSON格式返回

Java架构

k8s 节点机器重启 CNI IP 未回收

Geek_f24c45

Kubernetes cni

连续四年百度Android岗必问面试题!成长路线图

欢喜学安卓

android 程序员 面试 移动开发

宜信支付结算账户系统浅析-InfoQ