【微服务】--接口幂等性

什么是接口幂等性

接口幂等性是指:某些接口在被调用任意次数后,此接口对数据的操作每次结果都是相同的,即第一次操作和第N次操作接口的结果都是相同的,就像数学中某些数字的任意次幂其结果也都是数字本身。

不会产生接口幂等性的操作

在Java中有些操作其本身就是天然幂等性的,例如查询操作、删除操作、以下两条语句无论执行任意次,其结果都是相同的。

select * from user where id= 1
delete from user where id=1

部分更新操作,部分插入操作。

update user set age = 44 where id = 2

假设name字段或age字段有唯一性约束,此类的插入将是幂等性的操作

insert into user (name,age) values ('张三',33)

一个接口至少进行两次参数相同的操作,如果其结果都是相同的,那么则此接口就具有幂等性,否则反之。

那些情况下会发生接口幂等的问题

用户快速多次点击付款按钮 ,
用户页面回退再次提交,
由于网络问题,导致请求失败。 触发重试机制
自动提交的操作

解决接口幂等的方案

Token 机制
利用Token 令牌防止重复操作。在用户操作前向服务器获取一个具有唯一性的Token ,在操作时携带此Token ,由服务端验证此Token 是否存在,不存在则抛弃本次请求,如果存在则在验证token之后操作接口之前删除Token 。Token 可以存储在 Reids 数据库提高性能。
在这里插入图片描述
Token 获取、比较和删除必须是原子性。 redis.get(token) 、token.equals、redis.del(token),如果操作不具有原子性,可能导致,高并发下,都 get 到同样的数据,判断都成功,继续业务并发执行。

使用锁机制

  1. 数据库悲观锁
    select * from xxxx where id = 1 for update; 悲观锁使用时一般伴随事务一起使用,数据锁定时间可能会很长,需要根据实际情况选用。 另外要注意的是,id 字段一定是主键或者唯一索引,不然可能造成锁表的结果,处理起来会 非常麻烦。

  2. 数据库乐观锁
    这种方法适合在更新的场景中, update t_goods set count = count -1 , version = version + 1 where good_id=2 and version = 1 根据 version 版本,也就是在操作库存前先获取当前商品的 version 版本号,然后操作的时候 带上此 version 号。我们梳理下,我们第一次操作库存时,得到 version 为 1,调用库存服务 version 变成了 2;但返回给订单服务出现了问题,订单服务又一次发起调用库存服务,当订 单服务传如的 version 还是 1,再执行上面的 SQL 语句时,就不会执行;因为 version 已经变 为 2 了,where 条件就不成立。这样就保证了不管调用几次,只会真正的处理一次。 乐观锁主要使用于处理读多写少的问题。

业务层分布式锁

如果多个机器可能在同一时间同时处理相同的数据,比如多台机器定时任务都拿到了相同数 据处理,我们就可以加分布式锁,锁定此数据,处理完成后释放锁。获取到锁的必须先判断 这个数据是否被处理过。

各种唯一约束

1、数据库唯一约束 插入数据,应该按照唯一索引进行插入,比如订单号,相同的订单就不可能有两条记录插入。 我们在数据库层面防止重复。 这个机制是利用了数据库的主键唯一约束的特性,解决了在 insert 场景时幂等问题。但主键 的要求不是自增的主键,这样就需要业务生成全局唯一的主键。 如果是分库分表场景下,路由规则要保证相同请求下,落地在同一个数据库和同一表中,要 不然数据库主键约束就不起效果了,因为是不同的数据库和表主键不相关。

Redis set 防重

很多数据需要处理,只能被处理一次,比如我们可以计算数据的 MD5 将其放入 Redis 的 set, 每次处理数据,先看这个 MD5 是否已经存在,存在就不处理。

全局请求唯一 id

调用接口时,生成一个唯一 id,Redis 将数据保存到集合中(去重),存在即处理过。 可以使用 Nginx 设置每一个请求的唯一 id; proxy_set_header X-Request-Id $request_id;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
保证微服务接口幂等性是非常重要的,这样可以避免在重复请求或者并发操作时产生不一致的结果。以下是几种常见的方法来保证接口幂等性: 1. 使用唯一标识符:在每个请求中使用唯一的标识符来标记请求,服务端可以根据这个标识符来判断是否已经处理过该请求。例如,在HTTP请求中可以使用UUID作为请求的唯一标识符。 2. 使用乐观锁:在数据库操作中,可以使用乐观锁机制来实现幂等性。乐观锁基于版本号或者时间戳,在更新数据时比较版本号或者时间戳,如果发现不一致则说明数据已被其他请求修改,此时可以返回错误提示或者重试。 3. 幂等性检查:在服务端处理请求之前,先检查请求的内容是否已经处理过。可以通过查询数据库、缓存或者其他持久化存储来判断是否已经存在相同的请求。如果已经存在,则直接返回之前的处理结果而不是再次处理。 4. 原子操作:将多个操作组合成一个原子操作,确保整个操作过程是原子性的。例如,在数据库中使用事务来保证多个数据库操作的原子性,如果操作失败则进行回滚。 5. 幂等性设计:在设计接口时,尽量避免引入非幂等性操作。例如,不要设计会对同一资源进行多次增加或者删除的接口。 综上所述,通过使用唯一标识符、乐观锁、幂等性检查、原子操作和幂等性设计等方法,可以有效地保证微服务接口幂等性

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值