当前位置: 首页 > 后端技术 > Java

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

时间:2023-04-01 21:51:27 Java

幂等性在我们的工作中无处不在。涉及支付场景、下单等核心场景。也是分布式系统中遇到最多的问题。灾区。知道了幂等性的重要性,下面就详细介绍一下幂等性以及具体的解决方案,希望对大家有所帮助@mikechen什么是幂等?幂等性是数学和计算机科学中的一个概念。当一元运算是幂等的时,它对任何元素两次的影响将与它一次的结果相同。所谓接口幂等性,就是对某个资源进行一次和多次请求,资源本身应该得到相同的结果。也就是说,在多次调用接口的情况下,对系统的影响是一样的,这就是幂等性。为什么需要幂等性在业务开发中,我们经常会遇到重复提交,无论是因为网络问题收不到请求结果重新发起请求,还是前端运行抖动导致重复提交。在交易系统中,支付系统重复提交带来的问题尤为明显。比如用户在APP上多次点击提交订单,后台应该只生成一个订单。又如:向支付宝发起支付请求时,由于网络问题或系统bug需要重试,支付宝应该只扣一次钱,而不是多次重试,造成多次扣款。又如:现在是微服务时代,服务接口会被外部调用者多次调用(考虑网络中断重试等),为了防止多次外部调用多次改变系统数据状态,该服务被设计为幂等的,以防止多次重试并导致系统不一致。通过以上典型的支付场景就可以知道幂等性的重要性。那么问题来了,如何实现幂等,有哪些解决方案呢?下面我们就来说说吧。幂等解决方案数据库唯一主键数据库唯一主键的实现主要是利用数据库中主键唯一约束的特点。一般来说,唯一主键更适合“插入”的幂等性,可以保证只有一张表中可以存在具有该唯一主键的一条记录。唯一索引使用唯一索引可以避免添加脏数据。当插入重复数据时,数据库会抛出异常来保证数据的唯一性。创建唯一索引表的例子如下:CREATETABLE`table_name`(`id`intNOTNULLAUTO_INCREMENT,`orderid`varchar(32)NOTNULLDEFAULT''COMMENT'uniqueid',PRIMARYKEY(`id`),UNIQUEKEY`uq_orderid`(`orderid`)COMMENT'唯一约束')ENGINE=InnoDB;在使用数据库的唯一主键实现幂等性时,需要注意的是主键一般不使用数据库中的自增主键,而是使用分布公式globalID作为主键,所以以确保ID在分布式环境中的全局唯一性。适用操作:插入操作删除操作数据库乐观锁数据库??乐观锁方案一般只适用于执行“更新操作”的过程,我们可以提前在相应的数据表中增加一个额外的字段作为当前的版本标识数据。这样,每次更新数据库表中的数据时,都以版本标识为条件,取值为上次要更新的数据中版本标识的值。更新数据时,从表名中选择版本,xxx首先将其与版本号进行比较。如果不相等,说明已经有其他请求更新数据,会提示更新失败。updatetablenamesetcount=count+1,version=version+1whereversion=#{version}适用操作:update操作PRG模式Post/Redirect/Get是web开发设计模式,用于防止重复提交表单。默认情况下,向服务器提交Post请求后,如果直接刷新浏览器,会再次提交Post请求。访问电子商务网站时,使用Post请求提交订单。直接刷新浏览器很容易导致重复提交订单,这不是用户想要的。PRG方式就是为了让用户避免这种现象的发生。下面举例说明使用PRG方法避免重复提交Post请求。当服务器处理完Post请求后,会向用户的浏览器发送响应,指示用户的浏览器立即使用Get方法访问另一个URL。当用户的浏览器获取到Get请求的数据时,整个过程结束。这时,当用户刷新当前页面时,不会造成Post请求的重复提交。防复制Token令牌针对的是客户端连续点击或者调用者超时重试等情况,比如提交订单。这种操作可以使用Token机制来防止重复提交。简单来说,调用者在调用接口时,首先向后端请求一个全局ID(Token),并在请求中携带这个全局ID(Token最好放在Headers中),后端需要验证Token作为Key,将用户信息作为Value发送给Redis,进行key-value内容验证。如果Key存在且Value匹配,则执行删除命令,然后正常执行后续业务逻辑。如果没有对应的Key或者Value不匹配,会返回错误提示重复执行,保证幂等操作。上面我只是列出了解决幂等性的方案和思路。事实上,类似的解决方案还有很多。比如下单流程也可以结合前端拦截和更多的后端解决方案来保证唯一性。这些也需要结合你的实际业务场景,最终选择更适合你的方案,但凡事都离不开它,都保证一次操作,唯一约束,这就是幂等性的本质。作者简介mikechen,10年+大工厂架构经验,《BAT架构技术500期》系列文章作者,曾供职于阿里、淘宝、百度等一线互联网公司。阅读更多mikechen的互联网架构Java并发|JVM|MySQL|Spring|Redis|Distributed|高并发|架构师的技术文章关注“Mikechen的互联网架构”公众号,回复【架构】领取我的原创《300 期 + BAT 架构技术系列与 1000 + 大厂面试题答案》