Spring Boot 接口幂等插件使用
幂等概述
-
幂等性原本是数学上的概念,即使公式:f(x)=f(f(x)) 能够成立的数学性质。用在编程领域,则意为对同一个系统,使用同样的条件,一次请求和重复的多次请求对系统资源的影响是一致的。
-
幂等性是分布式系统设计中十分重要的概念,具有这一性质的接口在设计时总是秉持这样的一种理念:调用接口发生异常并且重复尝试时,总是会造成系统所无法承受的损失,所以必须阻止这种现象的发生。
-
实现幂等的方式很多,目前基于请求令牌机制适用范围较广。其核心思想是为每一次操作生成一个唯一性的凭证,也就是 token。一个 token 在操作的每一个阶段只有一次执行权,一旦执行成功则保存执行结果。对重复的请求,返回同一个结果(报错)等。参考《幂等性浅谈》
幂等处理实现
加入依赖
<dependency> <groupId>com.pig4cloud.plugin</groupId> <artifactId>idempotent-spring-boot-starter</artifactId> <version>0.0.1</version> </dependency>
配置 Redis 链接
- 默认情况下,可以不配置。理论是支持 redisson-spring-boot-starter 全部配置
spring: redis: host: 127.0.0.1 port: 6379
接口
@Idempotent(key = "#key", expireTime = 10, info = "请勿重复查询") @GetMapping("/test") public String test(String key) { return "success"; }
测试
- 10 个独立线程请求
-
执行查看结果,10 个请求只会有一个成功
-
查看后台异常报错,9 个异常报错满足预期
idempotent 注解说明
-
key: 幂等操作的唯一标识,使用 spring el 表达式 用#来引用方法参数 。 可为空则取当前 url + args 做请求的唯一标识
-
expireTime: 有效期 默认:1 有效期要大于程序执行时间,否则请求还是可能会进来
-
timeUnit: 时间单位 默认:s (秒)
-
info: 幂等失败提示信息,可自定义
-
delKey: 是否在业务完成后删除 key true:删除 false:不删除
幂等处理设计原理
-
1.请求开始前,根据 key 查询 查到结果:报错 未查到结果:存入 key-value-expireTime key=ip+url+args
-
2.请求结束后,直接删除 key 不管 key 是否存在,直接删除 是否删除,可配置
-
3.expireTime 过期时间,防止一个请求卡死,会一直阻塞,超过过期时间,自动删除 过期时间要大于业务执行时间,需要大概评估下;
-
4.此方案直接切的是接口请求层面。
-
5.过期时间需要大于业务执行时间,否则业务请求 1 进来还在执行中,前端未做遮罩,或者用户跳转页面后再回来做重复请求 2,在业务层面上看,结果依旧是不符合预期的。
-
6.建议 delKey = false。即使业务执行完,也不删除 key,强制锁 expireTime 的时间。预防 5 的情况发生。
-
7.实现思路:同一个请求 ip 和接口,相同参数的请求,在 expireTime 内多次请求,只允许成功一次。
-
8.页面做遮罩,数据库层面的唯一索引,先查询再添加,等处理方式应该都处理下。
-
9.此注解只用于幂等,不用于锁,100 个并发这种压测,会出现问题,在这种场景下也没有意义,实际中用户也不会出现 1s 或者 3s 内手动发送了 50 个或者 100 个重复请求,或者弱网下有 100 个重复请求;
总结

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
6张图循序渐进讲透Kubernetes Ingress资源对象
Kubernetes Ingress 只是 Kubernetes 中的一个普通资源对象,需要一个对应的 Ingress 控制器来解析 Ingress 的规则,暴露服务到外部,比如 ingress-nginx,本质上来说它只是一个 Nginx Pod,然后将请求重定向到其他内部(ClusterIP)服务去,这个 Pod 本身也是通过 Kubernetes 服务暴露出去,最常见的方式是通过 LoadBalancer 来实现的。同样本文我们希望用一个简单清晰的概述,让你来了解 Kubernetes Ingress 背后的东西,让你更容易理解使用的 Ingress。 我们可以使用 Ingress 来使内部服务暴露到集群外部去,它为你节省了宝贵的静态 IP,因为你不需要声明多个 LoadBalancer 服务了,此次,它还可以进行更多的额外配置。下面我们通过一个简单的示例来对 Ingress 进行一些说明吧。 简单 HTTP server 首先,我们先回到容器、Kubernetes 之前的时代。 之前我们更多会使用一个(Nginx)HTTP server 来托管我们的服务,它可以通过 HTTP ...
- 下一篇
mongodb内核源码实现、性能调优、最佳运维实践系列-command命令处理模块源码实现一
关于作者 前滴滴出行技术专家,现任OPPO文档数据库mongodb负责人,负责oppo千万级峰值TPS/十万亿级数据量文档数据库mongodb内核研发及运维工作,一直专注于分布式缓存、高性能服务端、数据库、中间件等相关研发。后续持续分享《MongoDB内核源码设计、性能优化、最佳运维实践》,Github账号地址:https://github.com/y123456yz 背景 <<transport_layer网络传输层模块源码实现>>中分享了mongodb内核底层网络IO处理相关实现,包括套接字初始化、一个完整mongodb报文的读取、获取到DB数据发送给客户端等。Mongodb支持多种增、删、改、查、聚合处理、cluster处理等操作,每个操作在内核实现中对应一个command,每个command有不同的功能,mongodb内核如何进行command源码处理将是本文分析的重点 此外,mongodb提供了mongostat工具来监控当前集群的各种操作统计。Mongostat监控统计如下图所示: 其中,insert、delete、updat...
相关文章
文章评论
共有0条评论来说两句吧...