首页 > 其他分享 >避免重复扣款:分布式支付系统的幂等性原理与实践

避免重复扣款:分布式支付系统的幂等性原理与实践

时间:2024-01-05 23:32:21浏览次数:33  
标签:重复 数据库 系统 业务 扣款 支付 ID 分布式

这是《百图解码支付系统设计与实现》专栏系列文章中的第(6)篇。

本文主要讲清楚什么是幂等性原理,在支付系统中的重要应用,业务幂等、全部幂等这些不同的幂等方案选型带来的收益和复杂度权衡,幂等击穿场景及可能的严重后果。

这也是支付公司面试的必考题目之一。

专栏地址:百图解码支付系统设计与实现

1. 什么是幂等性原理

幂等性是一个数学和计算机科学术语,用于描述无论操作执行多少次,都产生相同结果的属性。在软件行业,应用极其广泛,当我们说一个接口支持幂等时,无论调用多少次,对系统造成的结果是一致的

注意这里说的“对系统造成的结果是一致的”是指系统内部数据或状态的变更,不是指返回值。不同的系统设计,返回值可能是不一样的。

举个例子,你在淘宝免密支付10元,淘宝针对这笔订单调用支付宝支付接口进行支付,无论是调用1次,还是调用100次,最终只扣了你10元。但是第二次有可能返回“重复请求”,也有可能返回“支付成功”,这个取决于接口设计。也就是支付宝内部只扣了你10元,但是接口可能返回给商户是是不同的结果。

避免重复扣款:分布式支付系统的幂等性原理与实践_防重

我个人倾向于方案一,如果等幂等,就返回:重复请求。减少误解,虽然两种方案中系统都只扣了一次钱。


2. 为什么幂等性在支付系统中极其重要

支付系统必须以最高的可靠性和准确性处理交易,这对于用户信任至关重要。如果一个支付系统不能保证幂等性,可能会导致多次扣除同一笔费用,引发用户不满和法律责任,严重时就会有舆情风险,甚至会被吊销牌照。

一般情况下,支付系统的幂等性能力要求比电商系统要求更高,如果用户在电商下单多了,只要没有支付,用户还是可以忍受的,但一旦多扣了用户的钱,后果就会比较严重。

这也是为什么幂等性会是支付系统招人的面试必考题目之一。


3. 支付系统中应用幂等性的场景

幂等是针对重复请求的,支付系统一般会面临以下几个重复请求的场景:

  1. 用户多次点击支付按钮:在网络较差或系统过载情况下,用户由于不确定交易是否完成而重复点击。
  2. 自动重试机制:系统在超时或失败时重试请求,可能导致同一支付多次尝试。
  3. 网络数据包重复:数据包在网络传输过程中,复制出了多份,导致支付平台收到多次一模一样的请求。
  4. 异常恢复:在系统升级或崩溃后,未决事务需要根据已有记录恢复和完成。内部系统重发操作。


4. 幂等解决方案

4.1. 业务幂等

避免重复扣款:分布式支付系统的幂等性原理与实践_防重_02

所谓业务幂等,就是由各域自己把唯一性的交易ID作为数据库唯一索引,这样可以保证不会重复处理。

在数据库前面可以加一层缓存来提高性能,但是缓存只用于查询,查到数据认为就返回幂等成功,但是但不到,需要尝试插入数据库,插入成功后再刷新数据到缓存。

为什么要使用数据库的唯一索引做为兜底,是因为缓存是可能失效的。

在面临时经常有同学只回答到“使用redis分布式锁来实现幂等”,这是不对的。因为缓存有可能失效分布式锁只是用于防并发操作的一种手段,无法根本性解决幂等问题,幂等一定是依赖数据库的唯一索引解决。

大部分简单的支付系统只要有业务幂等基本也够用了。


4.2. 通用幂等组件

避免重复扣款:分布式支付系统的幂等性原理与实践_幂等性_03

每个域都要做幂等处理,那就单独出一个独立的幂等组件,各子业务系统通过引用这个公共JAR包解决。

适用场景:应用部署不太多的时候。如果应用非常多,独立幂等DB的连接池就不够用。


避免重复扣款:分布式支付系统的幂等性原理与实践_幂等性_04

这个时候,可以把幂等组件的代码共用,但是幂等数据库表使用业务系统的DB资源。解决独立幂等DB导致的连接数不够用的场景。


4.3. 通用幂等服务

避免重复扣款:分布式支付系统的幂等性原理与实践_防重_05

解决DB连接数不够用的第二个解决方案:幂等组件服务化。这样的坏处就是复杂度和耗时都会增加。


4.4. 全局幂等

避免重复扣款:分布式支付系统的幂等性原理与实践_幂等性_06

在多机房部署情况下,需要解决机房之间的幂等服务。这就使用到了全局幂等概念。

所谓全局幂等,就是多个机房共用一份幂等数据,这里面涉及的技术比较复杂,后面单独开一个章节讲。除了极少数全球部署的多活支付系统都用不上。


4.5. 通用幂等数据库表设计

核心字段:

uniqueKey:幂等主键,由各应用自定义,需要保证全局唯一性使用这个uniqueKey做hash后分库分表。比如商户的收单ID,上游的ID等。

appName: 应用名称,比如收单,支付等。

siteId:站点ID

extInfoMap:扩展字段,由各应用自定义,比如保存我方单号。


4.6. 方案选型建议

简单的支付系统,只需要使用业务幂等就够。

中型的支付系统,推荐使用通用幂等组件。这样方便运维。

全局幂等方案只有极少数公司会考虑。


5. 分布式场景下实现幂等性的挑战及应对

分布式支付系统面临的幂等性挑战核心有两点:

  1. 如何保证分布于不同地理位置数据中心的系统数据的一致性。
  2. 幂等数据和业务数据跨库事务一致性。比如幂等已经入库成功,但是业务数据库入库失败。

为了解决这些挑战,可以采取以下解决方案:

  1. 使用全局唯一的交易ID,跟踪每次支付请求,防止重复处理。
  2. 幂等住了之后,还需要继续查询业务数据,如果查询失败,仍然执行业务操作。
  3. 构建强大的状态机推进能力,严格定义事务各个状态的转换。
  4. 幂等服务的高可靠性。


6. 幂等被击穿场景及可能的严重后果

尽管有了上述措施,幂等性仍然可能因为以下原因失效:

  1. 在分布式系统中,由于同步延迟,导致多个节点未能即时识别重复请求。
  2. 请求流量切换。原本应该路由A机房的数据路由到了B机房,但是B机房的幂等数据缺失。
  3. 生成全局唯一ID的算法出现故障或人为变更,同一笔业务可能出现了2个业务ID。

在支付系统中,只要幂等被击穿,基本上都会出现资损事件。有时候是用户资损,有时候是平台资损。曾经碰到一个真实案例,上游域把某个幂等字段组成规则的取值变了,但是下游不知道,导致下游幂等失败,对同一笔业务处理了2次,直接资损数十万美金。


7. 结束语

幂等性是分布式支付系统的基本要求,对于确保交易的正确性和避免重复扣费至关重要。除开支付系统外,很多互联网应用基本上都需要有幂等能力。

有机会再单独讲讲全局幂等。

标签:重复,数据库,系统,业务,扣款,支付,ID,分布式
From: https://blog.51cto.com/u_16485618/9120436

相关文章

  • 分布式I/O模块在轨道交通的作用
    随着科技的不断发展,轨道交通系统正逐渐向智能化、高效化的方向转型。在这个过程中,分布式I/O模块作为一种先进的控制技术,发挥着越来越重要的作用。分布式I/O模块能够实现轨道交通系统的集中控制和分散操作。可以监测轨道交通水位、桥梁位移等参数保障铁轨安全运行。通过将各个子系统......
  • Apache SeaTunnel:探索下一代高性能分布式数据集成工具
    大家下午好,我叫刘广东,然后是来自ApacheSeaTunnel社区的一名Committer。今天给大家分享的议题是下一代高性能分布式海量数据集成工具,后面的整个的PPT,主要是基于开发者的视角去看待ApacheSeaTunnel。后续所有的讲解主要是可能会硬核偏技术一点,主要是ApacheSeaTunnel流程当中的一......
  • 用 SpringBoot+Redis 解决海量重复提交问题
    1前言在实际的开发项目中,一个对外暴露的接口往往会面临很多次请求,我们来解释一下幂等的概念:任意多次执行所产生的影响均与一次执行的影响相同。按照这个含义,最终的含义就是对数据库的影响只能是一次性的,不能重复处理。如何保证其幂等性,通常有以下手段:数据库建立唯一性索引,可以保......
  • 每日一题:给定一个字符串s,请你找出其中不含有重复字符得最长子串的长度
    每日一题:给定一个字符串s,请你找出其中不含有重复字符得最长子串的长度functiongetLongSubstring(s){letmap=newMap();letmax=0;letleft=0;for(leti=0;i<s.length;i++){if(map.has(s[i])&&map.get(s[i])>=left){left=map.get(s[i])+1;......
  • 太强了!全新一代分布式任务调度与计算框架!
    大家好,我是Java陈序员。我们在工作开发中,离不开任务调度。通过指定的间隔时间执行各类操作,来完成无需用户操作的任务。目前市场上,有一些编程语言本身自带的定时任务工具,如Java中Timer。也有一些比较成熟的定时任务框架,如Quartz。现在大部分系统都是使用分布式,分布式的任务调度......
  • [简道云] 表单开发-如何检索出差日期并禁止重复日期提交
    应用场景技术员申请出差,处理项目维护业务,但是部分员工,填报时经常记错日期,交叉登记出差日期,引发后续报销费用重复情况。已存在的表单功能登记出差开始日期,结束日期自动列出所选择范围的全部日期自动计算所选择范围的出差天数需要处理的问题新增一个字段,实现检索已录入的出差人员,出差......
  • 分布式日志追踪ID实战 | 京东物流技术团队
    本文通过介绍分布式应用下各个场景的全局日志ID透传思路,以及介绍分布式日志追踪ID简单实现原理和实战效果,从而达到通过提高日志查询排查问题的效率。背景开发排查系统问题用得最多的手段就是查看系统日志,相信不少人都值过班当过小秘吧:给下接口和出入参吧,麻烦看看日志里的有没有异常......
  • 8.Elasticsearch,分布式搜索引擎
    1.Elasticsearch入门Elasticsearch简介一个分布式的、Restful风格的搜索引擎。支持对各种类型的数据的检索。搜索速度快,可以提供实时的搜索服务。便于水平扩展,每秒可以处理PB级海量数据。Elasticsearch术语索引、类型、文档、字段。集群、节点、分片、副本。术......
  • fugue 分布式计算通用接口
    fugue提供了通用方便分布式计算的接口,可以高效的访问大数据项目,提供了python,pandas,sql等模式如下图从上图可以看出fugue提供了一个语义层,我们的计算任务可以运行在ray,dask,spark,以及duckdb中参考架构可以看出fugue提供了不少方便的能力,比如sql,机器学习,以及流处理说明对于搞机器......
  • 华为云分布式云原生UCS,助力MetaERP构建企业级高可用分布式业务
    本文分享自华为云社区《华为云分布式云原生UCS,助力MetaERP构建企业级高可用分布式业务》,作者:云容器大未来。▎引言华为云最近成为《ForresterWave™:MulticloudContainerPlatforms,Q42023》报告中唯一入选的中国厂商,市场表现强劲。华为云分布式云原生UCS作为本次参评的关键......