交易结算金额一致性保证
目录
一、背景
技术和业务的发展是分不开的。业务驱动技术的发展,技术反辅业务的提升。
1.1 结算交易产品介绍
1.2 为什么要做结算金额的保证
1、结算涉及到金钱,一旦金额不一致,则会导致大问题。
2、结算涉及的系统链路较长,涉及系统交互如下:
以下情况均会引起结算出错:
逻辑错误,如交易在错误的时机发起了结算、结算构造结算信息计算金额错误等
流程中断,如结算在RPC取得订单信息时超时等
消息重复,如发送多次消息到结算,但是消息产生了多条。会导致一次订单发起多次结算
消息丢失,如交易发送MQ到结算,但是消息丢失
消息乱序,如一个订单发起了一次正向结算,一次逆向结算,但是逆向结算消息先到,正向结算后到。
二、目标
针对以上问题,数据一致性的目标为以下三个:
不多发起结算
不少发起结算
不误发起结算
三、解决方法
对目标和问题进行组合,通过问题找到解决方法,得到目标、问题、方法的关系如下:
目标 |
遇到的问题 |
解决方法 |
---|---|---|
不多发起结算 |
消息重复 |
UK、状态机、乐观锁 |
消息乱序 |
状态机、乐观锁 |
|
逻辑错误 |
对账、补偿 |
|
不少发起结算 |
流程中断 |
分布式事务、重试、实时对账 |
逻辑错误 |
对账、补偿 |
|
消息丢失 |
对账 |
|
不误发起结算 |
逻辑错误 |
计算逻辑剥离+告警 对账 |
那如何选择方法来解决实际问题?
3.1 UK 和状态机
1)场景
各个系统的交互方式是MQ消息,且mafka支持流程中断重试功能,因此就会有以下两个问题:
重复请求问题
消息乱序问题
在解决此类问题时,可以用状态机、乐观锁、数据库UK来保证处理的幂等性以及顺序性。
各个方法的使用场景不一样,当实体上有状态流转时,可以采用状态机来解决。当实体上并不存在状态,例如商品的库存数量,可以采用乐观锁(版本号)来解决。
由于每个订单对应的结算记录都是有明确状态的,所以选用状态机。
2)实践
1、结算的UK
结算记录以订单号+流水号+结算类型(正向/逆向)为UK。防止一次支付或一次超退发起了多次结算
2、结算的状态机
3.2 金额校验+告警
1)场景
在向结算平台发起结算时,需要推送结算平台的金额信息有:用户支付金额,平台优惠金额,商户支付金额,总金额。而这些都是由订单金额计算得出,是有概率计算错误的。
2)实践
1、校验提交结算金额
四种金额经过金额类型分类计算后,必须满足公式:用户支付金额 + 平台优惠金额 + 商户支付金额 = 总金额。
2、金额错误时告警
一旦不满足此校验条件,则不发起结算,且通过告警系统告警。
对告警系统的要求是:
实时
需要能追溯当时发生的场景、参数,以便快速解决问题
最好能兼顾使用简单
在对比了团队告警和公司支持的两种告警系统后,团队系统比较适合场景,以下是团队告警和这两个系统的对比
系统 |
支持的告警类型 |
告警准确性 |
告警时效性 |
告警跟进情况统计 |
---|---|---|---|---|
CAT |
支持Transaction、problem等方式的配置告警,需要配置 |
准确 |
实时 |
无 |
LogCenter |
支持配置的日志告警 |
准确 |
分钟级别延迟 |
无 |
团队告警 |
支持实时监控、日志上报的方式告警,不需要配置,类似于Log4j |
准确率90%以上 |
实时 |
有 |
3.3 对账
3.3.1 实时对账
1)场景
在结算时,在以下环节都有可能出现流程中断
在解决流程中断时,可以有如下方法:
转化为本地事务
使用分布式事务
重试
实时对账发现流程中断
为什么选择实时对账呢?以下是对四种方式的对比以及选择的理由:
方法 |
适用场景 |
淘汰或选择理由 |
---|---|---|
本地事务 |
1.针对同一个系统内发生的操作 |
结算是会跨多个系统调用,不适合 |
分布式事务 |
1.针对跨系统的调用,不同的解决方案可以解决不同的场景。 |
分布式事务会带来代码复杂度,且需要重新开发,公司的swan还在开发中。不适合 |
重试 |
1.目标系统必须满足幂等 2.需要在确定是问题的情况下才知道重试 3.不需要一定成功的场景 |
因为系统之间交互是MQ方式,MQ本身已经支持重试,可以依赖MQ本身的重试机制。已经在使用。 |
实时对账发现流程中断 |
1.适合跨系统调用,对发现问题实时要求高,问题处理依赖于人为分析之后做决定的场景 |
满足实时要求 流程中断有可能是逻辑错误,实时对账可以发现问题 使用简单,只需要打几行日志即可
|
2)实践
针对有可能出现中断的环节,实时对账的要素如下:
中断问题序号 |
源数据 |
目标数据 |
触发规则 |
校验方式 |
差错处理 |
---|---|---|---|---|---|
1 |
交易发起结算时的订单号、结算类型 |
结算系统落地成功的结算记录 |
实时 |
一分钟内,源数据和目标数据: 订单号相等 结算类型相等 |
告警 |
2 |
结算系统落地成功的结算记录 |
收到结算平台处理成功的回执 |
实时 |
二十分钟内,源数据和目标数据: 订单号相等 结算类型相等 |
告警 |
3 |
收到结算平台处理成功的回执信息 |
成功更新结算系统记录为已完成 |
实时 |
二十分钟内,源数据和目标数据: 订单号相等 结算类型相等 |
告警 |
3.3.2 全量+增量对账
1)场景
在处理逻辑错误问题时,可以使用对账和补偿来解决。
其中对账可以发现问题,然后caseBycase处理。
补偿可以发现+部分解决问题。
由于业务单量较少,且对账发现的问题一般为逻辑问题,补偿并不一定能完全解决。所以采用对账来发现问题,发现问题后CaseByCase处理。
2)实践
全量对账的要素如下:
源数据 |
目标数据 |
触发规则 |
校验方式 |
差错处理 |
---|---|---|---|---|
历史的所有需要结算的正向/逆向订单 |
状态为已完成的正向/逆向结算记录 |
离线 |
源数据和目标数据: 订单号相等、流水号相等、结算类型相等 |
告警 |
增量对账的要素如下:
源数据 |
目标数据 |
触发规则 |
校验方式 |
差错处理 |
---|---|---|---|---|
当前时间20分钟(结算处理周期)前一个小时需要结算的统一订单 |
结算成功的结算记录 |
1小时 |
源数据和目标数据: 订单号相等、流水号相等、结算类型相等 |
告警 |
3.3.3 审计系统
针对对账的需求,团队衍生出了审计平台,支持实时 + 全量 + 增量对账。
1)审计平台适合的场景
1.数据的一致性
审计系统可以数据实体进行兜底的校验。
例如:逆向结算记录和订单的超退记录,应成对出现,如果结算表插入了逆向结算数据,但是超退没有出现,则代表数据出现了不一致。
2.二次校验
当线上出现一个可能是问题的异常时,需要使用相应的上下文再次进行另一种路径的校验,都失败时,则告警提示。
例:商业系统在c端查询查询某个商户下有没有技师的数据时,需要校验该商户有没有旺铺宝查询权限。当无旺铺宝查询权限时,需要校验该商户有没有录入过技师数据,如果录入过,则说明可能是由于查询权限配置问题导致的异常
2)审计平台支持的数据来源
1.自定义日志
用户可以通过审计系统提供的API进行日志上报。日志通过mafka异步上报至团队日志系统。一般适用于实时的行为对比场景
2.实现审计平台SPI
用户可以实现审计平台的源数据SPI和目标数据SPI,进行批量数据上报,审计系统通过配置的规则进行对比。一般适用于批量的数据对比场景
3)审计平台的功能架构
4)结算与审计系统的交互
1、实时对账时,以自定义日志作为源数据和目标数据源,两者成对匹配校验,得出对账结果,不能配对,则发送告警。
2、全量+增量对账时,结算系统实现审计系统的源数据SPI,返回结算记录信息。交易系统实现审计系统的目标数据SPI,返回统一订单信息。两者数据经过在审计系统配置的规则校验后,得出对账结果,结果不正确,则发送告警。
四、成果
1)对增量的订单结算,一旦有问题,则能实时发现
2)在对历史数据和增量数据梳理过程中。共发现以下问题:
发现4条错误的历史订单,其中:
1条结算平台已结算成功,但结算记录还是已发送状态
1条结算金额计算错误的历史订单
1条订单有超退记录,但是超退的结算未成功
1条订单有超退记录,但是不存在结算记录
发现2处历史逻辑错误:
齿科预定超退时,未对超退进行状态机校验
齿科预定更新结算状态时,未进行结算状态机校验
五、总结
本文主要讲述了在结算数据一致性上总结的方法以及实践:
1) 讲述了结算为什么需要数据一致性保证
2) 明确了结算一致性的目标
3) 总结了达到目标遇到的问题以及解决问题的方法论
4) 简单说明了在方法论上的一些实践。
交易结算金额一致性保证相关推荐
- kafka 脚本发送_Kafka笔记归纳(第五部分:一致性保证,消息重复消费场景及解决方式)...
写在开头: 本章是Kafka学习归纳第五部分,着重于强调Kafka的事一致性保证,消息重复消费场景及解决方式,记录偏移量的主题,延时队列的知识点. 文章内容输出来源:拉勾教育大数据高薪训练营. 一致性 ...
- 缓存与数据库一致性保证
缓存与数据库一致性保证 本文主要讨论这么几个问题: (1)啥时候数据库和缓存中的数据会不一致 (2)不一致优化思路 (3)如何保证数据库与缓存的一致性 一.需求缘起 上一篇<缓存架构设计细节二三 ...
- 微服务架构下的事务一致性保证
[转]微服务架构下的数据一致性保证(一) 今天分享第一篇,主要内容包括: 1.传统使用本地事务和分布式事务保证一致性. 2.传统分布式事务不是微服务中一致性的最佳选择. 3.微服务架构中应满足数据最终 ...
- mysql缓存一致性,缓存与数据库一致性保证
全是干货!本文主要讨论这么几个问题: (1)啥时候数据库和缓存中的数据会不一致 (2)不一致优化思路 (3)如何保证数据库与缓存的一致性 一.需求缘起 当数据发生变化时,"先淘汰缓存,再修改 ...
- mysql 主从一致性_mysql 主从一致性保证
MySQL 主备的基本原理 MySQL 主备切换流程.png 主备同步流程图 备库 B 跟主库 A 之间维持了一个长连接.主库 A 内部有一个线程,专门用于服务备库 B 的这个长连接. 一个事务日志同 ...
- Flink 状态一致性:端到端状态一致性的保证
文章目录 状态一致性 什么是状态一致性 状态一致性种类 端到端(end-to-end)状态一致性 Sink端到端状态一致性的保证 Flink+Kafka端到端状态一致性的保证 状态一致性 什么是状态一 ...
- 【Flink】介绍Flink中状态一致性的保证
1.概述 转载:介绍Flink中状态一致性的保证 再次温习了这篇文章有了不一样的收货.侵权可删,这里是方便自己找到. 1. 一致性 1.1 介绍状态一致性 有状态的流处理,内部每个算子任务都可以有自己 ...
- 即时消息:如何保证消息的一致性
什么是消息一致性 所谓消息收发一致性,一般指的是消息的时序一致性,也就是保证消息不会乱序 对于点对点的聊天场景,时序一致性需要保证接收方的接收顺序和发送方的发送顺序一致 对于群组聊天,时序一致性保证的 ...
- Flink如何保证数据的一致性
当在分布式系统中引入状态时,自然也引入了一致性问题.一致性实际上是"正确性级别"的另一种说法,也就是说在成功处理故障并恢复之后得到的结果,与没有发生任何故障时得到的结果相比,前者到 ...
- 事务的4个特性——ACID(原子性、一致性、隔离性和持久性)、更新丢失问题...
事务的4个特性--ACID(原子性.一致性.隔离性和持久性) 事务是一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位.事务通常以BEGIN TRANSACTION开始,以COMMI ...
最新文章
- python编程入门t-python高级编程——入门语法(一)
- JS 全局对象 全局变量 作用域 (改自TOM大叔博文)
- 许耀武:有趣有挑战的二十年
- 解决Coldfusion连接MySQL数据库的问题
- 我是新来的,希望大家以后能多指教.
- java 查找素数_在Java中查找和检查素数
- python挖矿脚本_利用公共WiFi挖矿的Python脚本(注:仅作研究使用)
- OpenCV——SURF特征检测、匹配与对象查找
- verilog学习笔记——三段式状态机
- Office2010每次打开都出现配置进度窗体
- Codeforces633H-Fibonacci-ish II
- 攻防世界 REVERSE 新手区/logmein
- pfamscan 的使用_InterProScan的使用教程
- Eclipse 使用中一些好用的快捷键
- win10邮件同步出错
- MIPI摄像头工程=7系列FPGA + OV5640(MIPI) + 15 分钟 + VITIS
- 计算机组成原理——奇偶校验,海明校验,循环冗余校验
- html 卡片布局 怎么,卡片式格局(CardLayout)
- 迎接Ubuntu Flatpak Remix,预装了Flatpak支持的Ubuntu
- python如果否则_Python传递参数(如果已定义),否则使用defau
热门文章
- STM32F7-->USART串口通信
- 关于数字IC设计中分频后的慢速时钟和以快时钟触发的信号的关系处理
- 实验吧 天网管理系统
- 虚拟机去虚拟化教程,过游戏检测,不全你打我
- 磊科路由器信号按键_超简单的磊科路由器重置方法
- 华为手机设置 网页打不开java_如何设置华为手机浏览器,打开后不会自动跳转......
- mysql生成连续数字或日期
- pip install:Requirement already satisfied
- Intellj IDEA 设置默认maven版本
- linux网络测试工具