免费下载!由 O’Reilly 出版的《NGINX 完全指南》中文版已正式上线 了解详情
写点什么

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

  • 2020-02-12
  • 本文字数:3087 字

    阅读完需:约 10 分钟

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

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


一、 账户体系


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-02-12 15:271375

评论

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

Github资源在线加速下载

xcbeyond

GitHub 工具类网站

DB-Engines 10月数据库排名:“三大王”无人能敌,PostgreSQL紧随其后

华章IT

数据库 postgresql Clickhouse MySQ

解密360容器云平台的Harbor高可用方案

博文视点Broadview

容器 高可用 云原生 k8s Harbor

对象的实例化内存布局与访问定位

朱华

Java 对象初始化

伯克利:serverless是下一代计算范式

华为云开发者联盟

云计算 服务

MySQL-技术专题-事务实现原理

洛神灬殇

链表反转的两种实现方法,后一种击败了100%的用户!

王磊

Java 数据结构 算法

Spring Cloud 微服务实践(8) - 部署

xiaoboey

Docker zookeeper 微服务 Spring Cloud actuator

程序员的美丽假期(并不)

Learun

程序员 敏捷开发 软件设计

MySQL-技术专题-MySQL的索引

洛神灬殇

水滴石穿之Java学习之路

价投小邱

Java 学习 后端

使用 Flutter 快速实现聊天应用

LeanCloud

flutter 后端 聊天

关于GO语言,这篇文章讲的很明白

华为云开发者联盟

编程语言 语言 Go 语言

看这里!带你快速体验MindSpore V1.0(For ubuntu 18.04)

华为云开发者联盟

华为 AI 技术

链表反转的两种实现方法,后一种击败了100%的用户

小Q

Java 程序员 数据结构 算法 开发

spring-boot-route(十四)整合Kafka

Java旅途

Java kafka Spring Boot

技术分享丨华为鲲鹏架构Redis知识二三事

华为云开发者联盟

redis 鲲鹏

LeetCode题解:83. 删除排序链表中的重复元素,HashMap,JavaScript,详细注释

Lee Chen

大前端 LeetCode

高难度对话读书笔记——聆听篇2

wo是一棵草

Aspose.pdf破解全程记录

janux

九面成功定级阿里资深架构师,拿到180W年薪+15000股,学习一下大神的成长之路!

Java架构追梦

Java 学习 架构 面试 微服务

滴滴导航若干关键功能的技术突破与实践

滴滴技术

人工智能 滴滴技术 滴滴导航

读10x程序员有感。

杨鹏Geek

程序员 10X工作法

字节跳动总结的这份《Java设计模式(实战+源码)》PDF突然火了,完整版免费开放下载!

Java架构之路

Java 程序员 字节跳动 编程语言 设计模式

英特尔为北京2022年冬奥会打造智慧新体验

新闻科技资讯

c++笔记——类

菜鸟小sailor 🐕

c++

MySQL-技术专题-存储引擎详解

洛神灬殇

四面阿里成功定级P6,想和Java程序员谈一谈

Java架构之路

Java 程序员 面试 编程语言

并发和Read-copy update(RCU)

程序那些事

并发 并发和RCU RCU

两年Java开发经验四面阿里成功拿下P6offer,总结大厂面试的心酸血泪史

Java架构之路

Java 程序员 面试 算法 编程语言

Minds Factory 2020 HUAWEI HiCar 创新活动

Jessie

物联网 创新 智能 汽车 大赛

宜信支付结算账户系统浅析_文化 & 方法_李锐 程留允_InfoQ精选文章