当前位置 博文首页 > 超负荷小生的博客:分布式--接口幂等性----相关知识点

    超负荷小生的博客:分布式--接口幂等性----相关知识点

    作者:[db:作者] 时间:2021-09-08 19:40

    1、什么是接口幂等性?
    接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。
    例子:支付场景,用户购买了商品并且支付扣款成功,但是返回结果时出现网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额返发现多扣钱了,流水记录也变成了两条。原因就是没有保证接口的幂等性
    2、什么情况下需要保证接口幂等性?
    用户多次点击按钮
    用户页面回退再次提交
    微服务互相调用,由于网络问题,导致请求失败。feign 触发重试机制
    其他业务情况
    3、sql操作中那些是天然幂等的?

    SELECT * FROM table WHER id=? #无论执行多少次都不会改变状态,是天然的幂等。
    UPDATE tab1 SET col1=1 WHERE col2=2 #无论执行成功多少次状态都是一致的, 也是幂等操作。
    delete from user where userid=1 #多次操作,结果一样,具备幂等性
    insert into user(id,name) values(1,'a'); #id是唯一主键,重复操作也只会插入一条用户数据,具备幂等性
    ——————————————不是幂等的—————————————————————————
    update tab1 set col1=col1+1 where col2 = 2, 如果每次执行的结果都会发生变化,不是幂等的。
    insert into user(id,name) values(1,'v'); 如果id不是主键,可以重复,也不具备幂等性
    

    4、幂等的解决方案
    第一种: 数据库解决级别,设置主键,建立索引
    在这里插入图片描述第二种: token机制
    1、服务端提供发送token的接口。在执行业务前,先去获取token,服务器会把token保存到redis中。
    2、调用业务接口请求,并携带token(放在头部)。
    3、服务器通过判断token是否存在redis中,存在表示第一次请求,执行删除操作后继续执行业务
    4、token不存在redis中,表示重复操作,直接返回给客户端,提示重复提交
    注意:redis中的获取和对比和删除必须是原子性的,如果这些操作不是原子性的,在高并发下,都get到同样的数据,判断都成功,继续业务并发执行则会出现业务问题

    第三种: 锁机制
    1、数据库的悲观锁
    2、数据库的乐观锁

    第四种: 各种唯一约束
    1、数据库唯一约束
    插入数据,应该按照唯一索引进行插入,比如订单号,相同的订单就不可能有两条记录插入。我们在数据库层面防止重复。这个机制是利用了数据库的主键唯一约束的特性, 解决了在insert场景时幂等问题。但主键的要求不是自增的主键,这样就需要业务生成全局唯一的主键。如果是分库分表场景下,路由规则要保证相同请求下,落在同一个数据库和同一表中,要不然数据库主键约束就不起效果了,因为是不同的数据库和表主键不相关。
    2、redis Set 防重
    很多数据需要处理,只能被处理一次,比如我们可以计算数据的MD5将其放入redis的set,每次处理数据,先看这个MD5是否已经存在,存在就不处理。

    第五种、 建立数据库中防重表

    第六种、 全局请求唯一id
    调用接口时,生成一个唯一id, redis 将数据保存到集合中(去重),存在即处理过。可以使用
    nginx设置每一个请求的唯一id; 但是nginx不会区分两次相同的请求,nginx对于两次相同的请求也会分配不同的id,进行如下设置
    proxy_ set_ header X-Request-ld Srequest id;

    cs