聊聊幂等
2022/3/18 23:29:14
本文主要是介绍聊聊幂等,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
什么是幂等
这里的幂等是参考的数学上的一个概念,在服务中的定义为多次执行所产生的影响均与一次执行的影响相同。
如何实现幂等
幂等没有一种专门的规则或者方法来实现,都是针对业务具体来做的。
幂等有多个可以讨论的维度。可以从大方向上按照操作(增删改查)来讨论。
- 查天然是幂等的。
- 按照唯一标识的删除也是天然幂等的。
- 按照唯一标识的更新,如果不依赖于现有值,也是幂等的。
- 新增操作、有条件的删除和更新,以及虽然按照唯一标识,但是依赖于现有值的更新都不是幂等的。
实现幂等有两个大方向:
- 防重复;
- 重复操作效果一致。
除了天然幂等的操作外,实现重复操作效果一致非常困难,因此一般幂等的解决思路就是防重复。防重复一般分为两步:
- 生成唯一令牌
- 验证唯一令牌
唯一令牌可以由客户端也可以由服务端生成。
- 客户端生成的话,保证的就是同一客户端的某一个操作只会执行一次,这种情况针对的是客户端重复提交的(包括用户自己重复提交和客户端自己的超时重试)。比如客户端发送一个通知给服务端,客户端会生成一个唯一ID,第一次请求超时后,第二次再用这个ID去请求,服务端需要记录下已经执行的唯一ID,下次再来这个ID时,就不会再一次进行操作。
- 服务端生成的话,一般是业务维度的标识,比如如果支付前需要先生成一笔交易,服务端可以将唯一的交易ID给客户端,客户端接下来的操作都是针对这个交易ID的。
- 服务端如果不用业务标识的话,效果就和客户端生成类似,可以将客户端的操作分为两步:第一步获取一个唯一ID,第二步是实际操作,并在操作中将唯一ID放入。
具体到服务端验证唯一令牌而言,一般有以下方式:
- 防重表,每次请求都去防重表中插入一条数据。如果重复就表示已经在处理了。有些文章所说的唯一索引其实也就是防重表的思路。
- 分布式缓存,可以在 Redis 集群中使用一个 Set 来进行排重。
唯一令牌是一种比较通用的方式,如果对于特定的一些业务,它的事务本身有状态,也可以用状态机配合锁来进行幂等。即先用分布式锁或数据库锁来锁住状态,然后修改状态。这样后来的事务发现状态改变就直接返回。
幂等和并发导致的数据不一致
幂等和并发导致的数据不一致是不一样的,并发下的数据不一致解决的是两个同一个时间区间内进行的事务,如何不相互影响。比如有些文章说到的分布式锁和 CAS,其实解决的是并发的情况下数据不一致的问题。
不过 CAS 如果配合版本号的话,也可以起到幂等的效果。比如操作前就给了客户端一个版本号 v1,接下来扣减操作就是 update t set amount = amount-10 where account=a and version=v1。这个本质还是令牌。但这种使用方式很变扭,相当于一个很长的锁了。
对那种 update t set amount = amount-10 where account=a and amount=old_amount 这种,并不能保证查出的 old_amount 就是正确的值,可能已经是前一次操作后的结果了,没有任何意义。这个只能解决并发下数据不一致的问题。
多层幂等
幂等还有一个问题在于一个系统中需要多层幂等。什么意思呢?A 发送请求给 B,B 处理的一部分是要发送请求给另一个系统 C,C 在处理的过程中还可能需要发请求给另一个系统 D…… D 处理完了返回给 C,C 返回给 B,B 返回给 A。在这个链条中,如果 A B C D 中任何一个系统并没有正确实现幂等,也就是出现了 “幂等漏洞”,那么一个请求还是有可能被多次执行,产生区别于一次执行的影响。
参考
每个工程师都应该了解的:聊聊幂等
这篇关于聊聊幂等的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15鸿蒙生态设备数量超8亿台
- 2024-05-13TiDB + ES:转转业财系统亿级数据存储优化实践
- 2024-05-09“2024鸿蒙零基础快速实战-仿抖音App开发(ArkTS版)”实战课程已上线
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?
- 2024-05-09这种运行结果里的10.100000001,怎么能最快改成10.1?