如何保证接口的幂等性 什么是幂等性 幂等性是系统服务对外一种承诺,承诺只要调用接口成功,外部多次调用对系统的影响是一致的。声明为幂等的服务会认为外部调用失败是常态,并且失败之后必然会有重试。 什么情况下需要幂等 接口调用下存在的问题: 现如今我们的系统大多拆分为分布式SOA,或者微服务,一套系统中包含了多个子系统服务,而一个子系统服务往往会去调用另一个服务,而服务调用服务无非就是使用RPC通信或者restful,既然是通信,那么就有可能在服务器处理完毕后返回结果的时候挂掉,这个时候用户端发现很久没有反应,那么就会多次按钮,这样请求有多次,那么处理数据的结果是否要统一呢?那是肯定的!尤其在支付场景。 一个场景: 假如客户账户Account1现在有100,执行一次交易(Order01)扣款10,现在有就变成了90,在分布式情况下,假如网络超时失败之类的情况下,就会导致可能客户端拿到了TimeoutException,但是实际上Server端执行成功了,这时客户端可能会发起重试,或者用MQ处理的话,MQ会重试。如果再执行一次就扣款10,就变成了80,显然这是不对的。况且如果重试操作发生了多次,余额被扣成了负数。理想的状态就是,多次的重复处理,结果应该不变,还是90。 如何保证幂等 天然幂等操作 1、查询操作:查询一次和查询多次,在数据不变的情况下,查询结果是一样的。select是天然的幂等操作; 2、删除操作:删除操作也是幂等的,删除一次和多次删除都是把数据删除。(注意可能返回结果不一样,删除的数据不存在,返回0,删除的数据多条,返回结果多个) ; 3、唯一索引:防止新增脏数据。比如:支付宝的资金账户,支付宝也有用户账户,每个用户只能有一个资金账户,怎么防止给用户创建资金账户多个,那么给资金账户表中的用户ID加唯一索引,所以一个用户新增成功一个资金账户记录。要点:唯一索引或唯一组合索引来防止新增数据存在脏数据(当表存在唯一索引,并发时新增报错时,再查询一次就可以了,数据应该已经存在了,返回结果即可) token机制: 防止页面重复提交 1、服务端提供了发送token的接口。我们在分析业务的时候,哪些业务是存在幂等问题的,就必须在执行业务前,先去token,服务器会把token保存到redis中。 2、然后调用业务接口请求时,把token携带过去,一般放在请求头部。 3、服务器判断token是否存在redis中,存在表示第一次请求,然后删除token,继续执行业务。 4、如果判断token不存在redis中,就表示是重复操作,直接返回重复标记给client,这样就保证了业务代码,不被重复执行。 关键点 先删除token,还是后删除token。 后删除token:如果进行业务处理成功后,删除redis中的token失败了,这样就导致了有可能会发生重复请求,因为token没有被删除。这个问题其实是数据库和缓存redis数据不一致问题,后续会写文章进行讲解。 先删除token:如果系统出现问题导致业务处理出现异常,业务处理没有成功,接口调用方也没有到明确的结果,然后进行重试,但token已经删除掉了,服务端判断token不存在,认为是重复请求,就直接返回了,无法进行业务处理了。 先删除token可以保证不会因为重复请求,业务数据出现问题。出现业务异常,可以让调用方配合处理一下,重新新的token,再次由业务调用方发起重试请求就ok了。 token机制缺点 业务请求每次请求,都会有额外的请求(一次token请求、判断token是否存在的业务)。其实真实的生产环境中,1万请求也许只会存在10个左右的请求会发生重试,为了这10个请求,我们让9990个请求都发生了额外的请求。 乐观锁机制:基于版本号version实现, 在更新数据那一刻校验数据 这种方法适合在更新的场景中, 根据version版本,也就是在操作库存前先当前商品的version版本号,然后操作的时候带上此version号。我们梳理下,我们第一次操作库存时,得到version为1,调用库存服务version变成了2;但返回给订单服务出现了问题,订单服务又一次发起调用库存服务,当订单服务传如的version还是1,再执行上面的sql语句时,就不会执行;因为version已经变为2了,where条件就不成立。这样就保证了不管调用几次,只会真正的处理一次。 乐观锁主要使用于处理读多写少的问题。 唯一主键(唯一索引):防止新增脏数据 这个机制是利用了数据库的主键唯一约束的特性,解决了在insert场景时幂等问题。但主键的要求不是自增的主键,这样就需要业务生成全局唯一的主键。 如果是分库分表场景下,路由规则要保证相同请求下,落地在同一个数据库和同一表中,要不然数据库主键约束就不起效果了,因为是不同的数据库和表主键不相关。 唯一ID 调用接口时,生成一个唯一id,redis将数据保存到集合中(去重),存在即处理过,这种是强校验场景,比如和金钱相关的场景,唯一id号可以当作一个订单号。
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/31725.html