最近遇到个问题是在网络延迟的时候,用户多次点击,最后这几次请求都发送到了服务器访问相关的接口,最后执行插入。
既然知道了原因,该如何解决。当时我的第一想法就是用注解 + AOP。通过在自定义注解里定义一些相关的字段,比如过期时间即该时间内同一用户不能重复提交请求。然后把注解按需加在接口上,最后在拦截器里判断接口上是否有该接口,如果存在则拦截。
解决了这个问题那还需要解决另一个问题,就是怎么判断当前用户限定时间内访问了当前接口。其实这个也简单,可以使用Redis来做,用户名 + 接口 + 参数啥的作为唯一键,然后这个键的过期时间设置为注解里过期字段的值。设置一个过期时间可以让键过期自动释放,不然如果线程突然歇逼,该接口就一直不能访问。
这样还需要注意的一个问题是,如果你先去Redis获取这个键,然后判断这个键不存在则设置键;存在则说明还没到访问时间,返回提示。这个思路是没错的,但这样如果获取和设置分成两个操作,就不满足原子性了,那么在多线程下是会出错的。所以这样需要把俩操作变成一个原子操作。
1.导入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.15.0</version>
</dependency>
2.使用注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NoRepeat {
/**
* 锁名称
*/
String lockName() default "no-repeat-default-lock-";
/**
* 参数key,支持Spel
*/
String key() default "";
/**
* 获取锁的最长时间,单位默认为秒
*/
long waitTime() default 5;
/**
* 租赁时间
解决网络延迟下的重复请求:AOP+Redis实现并发控制

本文探讨了在网络延迟导致用户多次点击时,如何通过自定义注解和AOP技术结合Redis来实现请求限频,确保同一用户在设定时间内只能发送一次请求。作者详细介绍了如何配置依赖、应用注解、编写切面,并强调了使用Redis原子操作的重要性。
最低0.47元/天 解锁文章
8710

被折叠的 条评论
为什么被折叠?



