什么是幂等性?四种接口幂等性方案详解!

简介: 本文深入分布式系统中的幂等性问题及其解决方案,涵盖数据库唯一主键、乐观锁、PRG模式和防重Token等方法,关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。

关注△mikechen的互联网架构△,10年+BAT架构经验倾囊相授

image.png

大家好,我是 mikechen | 陈睿 。

在我们的工作中,幂等性无处不在,无论是支付场景、还是下订单等核心场景,都会有所涉及,既是分布式系统最常遇到的问题,也是大厂面试的重灾区。

知道了幂等性的重要性,下面我就详细介绍幂等性以及具体的解决方案,希望对大家有所帮助@mikechen

什么是幂等性

幂等是一个数学与计算机学概念,在数学中某一元运算为幂等时,其作用在任一元素两次后会和其作用一次的结果相同。

所谓接口幂等性,就是一次和多次请求某一个资源对于资源本身应该具有同样的结果。

image.png

也就是说,在接口重复调用的情况下,对系统产生的影响是一样的,这就是幂等性。

为什么需要幂等性

业务开发中,经常会遇到重复提交的情况,无论是由于网络问题无法收到请求结果而重新发起请求,或是前端的操作抖动而造成重复提交情况。

在交易系统,支付系统这种重复提交造成的问题有尤其明显,比如:用户在APP上连续点击了多次提交订单,后台应该只产生一个订单。

image.png

再比如:向支付宝发起支付请求,由于网络问题或系统BUG重试,支付宝应该只扣一次钱,而不是多次重试,造成多次扣钱。

再比如:现在是微服务的时代,服务化接口在外部调用者会存在多次调用的情况(考虑网络中断重试等),为了防止外部多次调用对系统数据状态的发生多次改变,将服务设计成幂等,就是为了防止多次重试,造成系统不一致的问题。

通过以上典型的支付场景就知道幂等性的重要性了,那问题来了,如何实现幂等性,有哪些解决方案?下面我们接着聊。

幂等性的解决方案
数据库唯一主键
数据库唯一主键的实现主要是利用数据库中主键唯一约束的特性,一般来说唯一主键比较适用于“插入”时的幂等性,其能保证一张表中只能存在一条带该唯一主键的记录。

唯一索引 使用唯一索引可以避免脏数据的添加,当插入重复数据时数据库会抛异常,保证了数据的唯一性。

唯一索引表的创建示例如下:

CREATE TABLE `table_name` (

  `id` int NOT NULL AUTO_INCREMENT,

  `orderid` varchar(32) NOT NULL DEFAULT '' COMMENT '唯一id',

  PRIMARY KEY (`id`),

  UNIQUE KEY `uq_orderid` (`orderid`) COMMENT '唯一约束'

) ENGINE=InnoDB;

使用数据库唯一主键完成幂等性时需要注意的是,该主键一般来说并不是使用数据库中自增主键,而是使用分布式 全局ID 充当主键,这样才能能保证在分布式环境下 ID 的全局唯一性。

数据库乐观锁

数据库乐观锁方案一般只能适用于执行“更新操作”的过程,我们可以提前在对应的数据表中多添加一个字段,充当当前数据的版本标识。

这样每次对该数据库该表的这条数据执行更新时,都会将该版本标识作为一个条件,值为上次待更新数据中的版本标识的值。

select version from tablename where xxx

更新数据时首先和版本号作对比,如果不相等说明已经有其他的请求去更新数据了,提示更新失败。

update tablename set count=count+1,version=version+1 where version=#{version}

PRG 模式

Post/Redirect/Get 是一种 web 开发设计模式,用于防止表单的重复提交。

默认情况,提交 Post 请求到服务器后,如果直接刷新浏览器,会重新在提交一次 Post 请求。

image.png

在访问电商网站时,提交订单采用的是 Post 请求,如果直接刷新浏览器就容易导致重复订单的提交,这个不是用户希望发生的行为。

PRG 方法就是用户防止这种现象的发生,下面例图描述了用 PRG 方法来避免 Post 请求的重复提交。

当服务器处理完 Post 请求后,会发响应给用户浏览器,指示用户浏览器用 Get 方式立刻访问另一条 URL ,用户浏览器拿到 Get 请求的数据,整个流程才算结束。

image.png

此时用户刷新当前页面,也不会引起 Post 请求的重复提交了。

防重 Token 令牌

针对客户端连续点击或者调用方的超时重试等情况,例如提交订单,此种操作就可以用 Token 的机制实现防止重复提交。

简单的说就是调用方在调用接口的时候先向后端请求一个全局 ID(Token),请求的时候携带这个全局 ID 一起请求(Token 最好将其放到 Headers 中),后端需要对这个 Token 作为 Key,用户信息作为 Value 到 Redis 中进行键值内容校验,如果 Key 存在且 Value 匹配就执行删除命令,然后正常执行后面的业务逻辑。

image.png

如果不存在对应的 Key 或 Value 不匹配就返回重复执行的错误信息,这样来保证幂等操作。

上面我只是列举了解决幂等性的解决方案与思路,其实还有很多类似解决方案,比如订单流程还可以结合前段拦截,以及更多的后端方案来保障唯一性。

这些还需要结合你的实际业务场景,来最终来选择更适合你的解决方案,但是万变不离其中,都是为了保证一次操作,保证唯一约束,这才是幂等性的本质。

以上,是分布式缓存详细解析,欢迎评论区留言交流或拓展。

我是 mikechen | 陈睿 ,关注【mikechen的互联网架构】,10年+BAT架构技术倾囊相授。

本文已同步我的技术博客 www.mikechen.cc,更新至我原创的《30W+字大厂架构技术合集》中。

相关文章
|
SQL 缓存 NoSQL
接口的幂等性设计和防重保证,详细分析幂等性的几种实现方法
本篇文章详细说明了幂等性,解释了什么是幂等性,幂等性的使用场景,讨论了幂等和防重的概念。分析了幂等性的情况以及如何设计幂等性服务。阐述了幂等性实现防重的几种策略,包括乐关锁,防重表,分布式锁,token令牌以及支付缓冲区。
8333 0
接口的幂等性设计和防重保证,详细分析幂等性的几种实现方法
|
前端开发 NoSQL JavaScript
常见接口和服务幂等性问题及解决方案
常见接口和服务幂等性问题及解决方案
650 0
接口幂等性设计
接口幂等性设计
150 1
|
存储 缓存 监控
美团面试:说说OOM三大场景和解决方案? (绝对史上最全)
小伙伴们,有没有遇到过程序突然崩溃,然后抛出一个OutOfMemoryError的异常?这就是我们俗称的OOM,也就是内存溢出 本文来带大家学习Java OOM的三大经典场景以及解决方案,保证让你有所收获!
5406 0
美团面试:说说OOM三大场景和解决方案? (绝对史上最全)
|
4月前
|
人工智能 Java 数据库
如何保证接口幂等性?
在分布式系统中,接口幂等性至关重要。本文详解其定义、重要性及实现方案,包括唯一索引、Token机制、分布式锁、状态机与版本号机制,并提供最佳实践建议,助你提升系统可靠性与用户体验。
524 1
|
11月前
|
SQL 关系型数据库 MySQL
大厂面试官:聊下 MySQL 慢查询优化、索引优化?
MySQL慢查询优化、索引优化,是必知必备,大厂面试高频,本文深入详解,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验分享。
大厂面试官:聊下 MySQL 慢查询优化、索引优化?
|
11月前
|
消息中间件 中间件 Kafka
分布式事务最全详解 ,看这篇就够了!
本文详解分布式事务的一致性及实战解决方案,包括CAP理论、BASE理论及2PC、TCC、消息队列等常见方案,助你深入理解分布式系统的核心技术。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
分布式事务最全详解 ,看这篇就够了!
|
9月前
|
Prometheus 监控 Cloud Native
高频面题: 你们线上 QPS 多少?你 怎么知道的?
本文由45岁资深架构师尼恩撰写,针对高级开发和架构师面试中的高频问题提供详细解答。文章涵盖了QPS、TPS、RT等性能指标的定义及计算方法,详解了如何配置Prometheus与Grafana监控系统QPS,并提供了应对高并发场景(如双十一抢购)的系统部署策略。此外,还分享了多个大厂面试真题及解决方案,帮助读者在面试中充分展示技术实力,提升求职竞争力。建议收藏并深入学习,为面试做好充分准备。更多内容可参考《尼恩Java面试宝典》及相关技术圣经系列PDF。
|
11月前
|
消息中间件 存储 Java
吃透 RocketMQ 消息中间件,看这篇就够了!
本文详细介绍 RocketMQ 的五大要点、核心特性及应用场景,涵盖高并发业务场景下的消息中间件关键知识点。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
吃透 RocketMQ 消息中间件,看这篇就够了!