当前位置: 首页 > Linux

如何保证接口的幂等性

时间:2023-04-06 03:31:47 Linux

什么是幂等?幂等性是系统服务对外界做出的承诺。它承诺只要接口调用成功,多次外部调用对系统的影响是一致的。声明为幂等的服务将假设外部调用失败是正常的,并且失败后必须重试。什么情况下需要幂等?以SQL为例:SELECTcol1FROMtab1WHERcol2=2,无论执行多少次都不会改变状态,这是天然的幂等性。UPDATEtab1SETcol1=1WHEREcol2=2,无论执行多少次,状态都是一致的,所以也是幂等操作。UPDATEtab1SETcol1=col1+1WHEREcol2=2,每次执行的结果都会变,这个不是幂等的。insertintouser(userid,name)values(1,'a')如果userid是唯一的主键,即重复上面的业务,只会插入一条用户数据,是幂等的。如果userid不是主键,可以重复,那么多次操作上述业务会导致多条新的数据条目,不幂等。deletefromuserwhereuserid=1,多次操作,结果相同,具有幂等性如何保证幂等令牌机制1、服务端提供发送令牌的接口。我们在分析业务的时候,哪些业务存在幂等问题,在执行业务之前首先要获取到token,服务器会把token保存在redis中。2、然后在调用服务接口请求的时候,把token带过来,一般在请求的header中。3、服务端判断redis中是否存在token,存在则表示第一次请求,然后删除token,继续执行业务。4.如果判断token在redis中不存在,则表示重复操作,将重复标记直接返回给客户端,保证业务代码不会被重复执行。关键是先删除token,还是后删除token。事后删除token:如果业务处理成功后,redis中的token删除失败,可能会因为没有删除token而导致重复请求。这个问题其实是数据库和缓存的redis数据不一致的问题,后面会写一篇文章来说明。先删除token:如果系统出现问题,业务流程异常,业务流程不成功,接口调用方没有得到明确的结果,再试,但是token已经被删除了,服务器判断token不存在,认为如果是重复请求,直接返回,无法进行业务处理。先删除token可以保证业务数据不会因为重复请求而出现问题。如果出现业务异常,调用方可以配合处理,重新获取新的token,业务调用方再次发起重试请求就可以了。token机制的缺点业务请求每次请求都会额外请求一次(获取token请求并判断token是否存在的业务)。实际上,在真实的生产环境中,10000个请求可能只有10个左右的请求会被重试。对于这10个请求,我们让9990个请求产生额外的请求。乐观锁机制该方法适用于更新场景,updatet_goodssetcount=count-1,version=version+1wheregood_id=2andversion=1根据version版本,即在操作之前获取当前商品inventoryversion版本号,然后在操作的时候带上这个版本号。让我们解决一下。我们第一次操作库存的时候拿到的是版本1,调用库存服务的版本变成了2;但是返回订单服务出现问题,订单服务再次发起对库存服务的调用。当订单服务通过时,版本还是1,执行上面的SQL语句时,不会执行;因为版本变成了2,所以where条件就不成立了。这样可以保证无论调用多少次,都只会处理一次。乐观锁主要用来处理读多写少的问题。唯一主键机制利用数据库主键的唯一性约束来解决插入场景下的幂等问题。但是对主键的要求不是自增主键,需要业务生成一个全局唯一的主键。在分库分表的场景下,路由规则必须保证同一个请求落在同一个数据库同一个表中,否则数据库主键约束是没有作用的,因为不同数据库的主键和表是无关紧要的。防重表使用订单号orderNo作为去重表的唯一索引,将唯一索引插入到去重表中,然后进行业务操作,它们在同一个事务中。这样可以保证重复请求时,由于去重表有唯一约束,请求失败,避免了幂等问题。这里需要注意的是,去重表和业务表要在同一个库中,这样才能保证在同一个事务中,即使业务运行失败,去重表中的数据也会回滚。这是数据一致性的一个很好的保证。唯一ID调用接口时,生成唯一ID,redis将数据保存在集合中(去重),存在就处理。