小呆呆的生活

  • 首页
  • 分类
    • Linux
    • MySQL
    • SpringBoot
    • SpringCloud
  • 工具
  • 留言
  • 登录
  • 注册
  • 友情链接
    • 咸鱼的窝
    • DIY熙的家
    • Farmer的自习室
    • Dark的小黑屋
  • 关于
人的一生注定会遇到两个人
一个惊艳了时光,一个温柔了岁月
  1. 首页
  2. 其他
  3. 正文

幂等性设计

2021年 12月 29日 798次阅读 2人点赞 0条评论

幂等

幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。

接口幂等性

接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致。

使用场景

1、前端重复提交

用户注册,用户创建商品等操作,前端都会提交一些数据给后台服务,后台需要根据用户提交的数据在数据库中创建记录。如果用户不小心多点了几次,后端收到了好几次提交,这时就会在数据库中重复创建了多条记录。这就是接口没有幂等性带来的 bug。

2、接口超时重试

对于给第三方调用的接口,有可能会因为网络原因而调用失败,这时,一般在设计的时候会对接口调用加上失败重试的机制。如果第一次调用已经执行了一半时,发生了网络异常。这时再次调用时就会因为脏数据的存在而出现调用异常。

3、消息重复消费

在使用消息中间件来处理消息队列,且手动 ack 确认消息被正常消费时。如果消费者突然断开连接,那么已经执行了一半的消息会重新放回队列。当消息被其他消费者重新消费时,如果没有幂等性,就会导致消息重复消费时结果异常,如数据库重复数据,数据库数据冲突,资源重复等。

解决方法

1.Token机制

流程:

  1. 客户端会先发送一个请求去获取 token,服务端会生成一个全局唯一的 ID 作为 token 保存在 redis 中,同时把这个 ID 返回给客户端
  2. 客户端第二次调用业务请求的时候必须携带这个 token
  3. 服务端会校验这个 token,如果校验成功,则执行业务,并删除 redis 中的 token
  4. 如果校验失败,说明 redis 中已经没有对应的 token,则表示重复操作,直接返回指定的结果给客户端

注意:

  1. 对 redis 中是否存在 token 以及删除的代码逻辑建议用 Lua 脚本实现,保证原子性
  2. 全局唯一 ID 可以用百度的 uid-generator、美团的 Leaf 去生成

2.防重表

利用唯一索引的特性

流程:

  1. 建立一张去重表,其中某个字段需要建立唯一索引
  2. 客户端去请求服务端,服务端会将这次请求的一些信息插入这张去重表中
  3. 因为表中某个字段带有唯一索引,如果插入成功,证明表中没有这次请求的信息,则执行后续的业务逻辑
  4. 如果插入失败,则代表已经执行过当前请求,直接返回

3.Redis的SETNX 命令

这种实现方式是基于 SETNX 命令实现的,SETNX key value:将 key 的值设为 value ,当且仅当 key 不存在。若给定的 key 已经存在,则 SETNX 不做任何动作。该命令在设置成功时返回 1,设置失败时返回 0。

流程:

  1. 客户端先请求服务端,会拿到一个能代表这次请求业务的唯一字段
  2. 将该字段以 SETNX 的方式存入 redis 中,并根据业务设置相应的超时时间
  3. 如果设置成功,证明这是第一次请求,则执行后续的业务逻辑
  4. 如果设置失败,则代表已经执行过当前请求,直接返回

参考文档

  • 维基百科
  • 深入理解幂等性 - java懒洋洋
  • 使用token机制实现接口幂等性校验_悟空码字的博客
  • 阿里面试官:接口的幂等性怎么设计
  • 高并发的核心技术-幂等的实现方案
  • 幂等性如何实现
本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 其他
最后更新:2021年 12月 29日

小呆呆

知足常乐,就会拥有幸福

点赞

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

小呆呆

知足常乐,就会拥有幸福

最新 热点 随机
最新 热点 随机
数据库索引简析 Java多线程的使用场景以及线程的创建方式 Spring事务的使用示例和传播行为以及失效场景 Spring Boot使用JUnit和Mockito进行Service层单元测试 Spring Cloud Zuul和Gateway的简单示例(搭建方式) Spring Cloud的网关Zuul和Gateway
MySQL练习(三) SpringCloud五大核心组件 修复bug翻车记录 Reids客户端Jedis的访问模式(上) 初识消息队列 SSL证书介绍
标签聚合
SpringBoot 干货 SpringCloud 后端 面试 MySQL Java Spring
最近评论
我是可是尼古拉斯·爱新觉·罗·G·钰豪啊 发布于 3 年前(04月08日) 我来注水了胜哥 :hehe:
鸟人金 发布于 3 年前(03月03日) v
鸟人金 发布于 3 年前(03月03日) 胜哥yyds
鸟人金 发布于 3 年前(03月03日) 我滴偶像!!!!!!!!!!!!!!!
水军2号 发布于 3 年前(03月03日) 胜哥tql
归档
  • 2024 年 2 月
  • 2024 年 1 月
  • 2023 年 12 月
  • 2023 年 11 月
  • 2023 年 10 月
  • 2023 年 8 月
  • 2023 年 6 月
  • 2022 年 11 月
  • 2022 年 8 月
  • 2022 年 6 月
  • 2022 年 4 月
  • 2022 年 3 月
  • 2022 年 1 月
  • 2021 年 12 月
  • 2021 年 9 月
  • 2021 年 8 月
  • 2021 年 6 月
  • 2021 年 4 月
  • 2020 年 10 月
  • 2020 年 9 月
  • 2020 年 8 月
  • 2020 年 7 月
  • 2020 年 6 月
  • 2020 年 5 月
  • 2020 年 4 月
  • 2020 年 3 月

COPYRIGHT © 2023 小呆呆的生活. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

粤ICP备2020104583号

粤公网安备44011802000463号