使用Redis实现接口防抖

说明:实际开发中,我们在前端页面上点击了一个按钮,访问了一个接口,这时因为网络波动或者其他原因,页面上没有反应,用户可能会在短时间内再次点击一次或者用户以为没有点到,很快的又点了一次。导致短时间内发送了两个请求到后台,可能会导致数据重复添加。

为了避免短时间内对一个接口访问,我们可以通过AOP+自定义注解+Redis的方式,在接口上加一个自定义注解,然后通过AOP的前置通知,在Redis中存入一个有效期的值,当访问接口时这个值还未过期,则抛出异常,以此来避免短时间内对接口的方法。

实现

第一步:创建一个自定义注解,设置两个属性,一个是key,一个是这个key在Redis中的有效时间;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LimitAccess {

    /**
     * 限制访问的key
     * @return
     */
    String key();

    /**
     * 限制访问时间
     * @return
     */
    int times();
}

第二步:创建对应的Aspect;

import com.hezy.annotation.LimitAccess;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

/**
 * AOP类(通知类)
 */
@Component
@Aspect
public class LimitAspect {

    @Autowired
    private RedisTemplate redisTemplate;

    @Pointcut("@annotation(com.hezy.annotation.LimitAccess)")
    public void pt(){};

    @Around("pt()")
    public Object aopAround(ProceedingJoinPoint pjp) throws Throwable {
        // 获取切入点上面的自定义注解
        Signature signature = pjp.getSignature();

        MethodSignature methodSignature = (MethodSignature) signature;

        // 获取方法上面的注解
        LimitAccess limitAccess = methodSignature.getMethod().getAnnotation(LimitAccess.class);

        // 获取注解上面的属性
        int limit = limitAccess.times();
        String key = limitAccess.key();

        // 根据key去找Redis中的值
        Object o = redisTemplate.opsForValue().get(key);

        // 如果不存在,说明是首次访问,存入Redis,过期时间为limitAccess中的time
        if (o == null) {
            redisTemplate.opsForValue().set(key, "", limit, TimeUnit.SECONDS);
            // 执行切入点的方法
            return pjp.proceed();
        } else {
            // 如果存在,说明不是首次访问,抛出异常
            throw new RuntimeException("访问过于频繁");
        }
    }
}

第三步:在需要限制的接口上,加上这个注解,并设置key和限制访问时间,如下这个这个接口,设置key为set,实际开发中可以设置一个随机值,或者按照规则自定义设置,times为限制访问时间;

    @GetMapping("/limit")
    @LimitAccess(key = "limit", times = 10)
    public String limit() {
        return "success";
    }

演示

启动项目,访问该接口;

(首次访问,没得问题,同时在Redis中存入值)

在这里插入图片描述


(短时间内,连续访问,因为Redis中值未过期)

在这里插入图片描述

在这里插入图片描述


(10秒之后再访问,又可以了,Redis中的值过期了)

在这里插入图片描述

以上就是使用Redis实现接口防抖,避免短时间内连续访问接口。实际开发中,可以将异常设置为自定义异常。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/201397.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot的电影院管理系统的设计与实现 (含论文和源码视频导入教程)

👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于springboot的电影院管理系统7拥有两种角色 管理员:用户管理、购票统计、电影管理、电影类型管理、放映厅管理、订单管理等 用户:登录注册、查看各种信息、购票…

uniapp打包ios有时间 uniapp打包次数

我们经常用的解决方案有,分包,将图片上传到服务器上,减少插件引入。但是还有一个方案好多刚入门uniapp的人都给忽略了,就是在源码视图中配置,开启分包优化。 1.分包 目前微信小程序可以分8个包,每个包的最大存储是2M,也就是说你文件总体的大小不能超过16M,每个包的大…

【模板】KMP算法笔记

练习链接:【模板】KMP - 洛谷 题目: 输入 ABABABC ABA 输出 1 3 0 0 1 思路: 根据题意,用到的是KMP算法,KMP算法思想是通过一个一个匹配首字母的原理进行整个匹配效果,当某个首字母不匹配的时候&#x…

箭头函数与普通函数:谁更胜一筹?

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

ASUS(华硕) B760M-AYW WIFI D4_解决wifi不能使用

1、最近新购买了一套 diy电脑主机,选用的是 ASUS B760M-AYW WIFI D4电脑主板 win10 系统,到货后 发现右下角电脑图标处及网络适配器中 没有wifi选项 首先 在官网和旗舰店客服处,确认了 该主板 有集成wifi模块,鲨鱼鳍天线未安装…

Java数据结构之《直接插入排序》问题

一、前言: 这是怀化学院的:Java数据结构中的一道难度中等的一道编程题(此方法为博主自己研究,问题基本解决,若有bug欢迎下方评论提出意见,我会第一时间改进代码,谢谢!) 后面其他编程题只要我写完…

GoLang切片

一、切片基础 1、切片的定义 切片(Slice)是一个拥有相同类型元素的可变长度的序列它是基于数组类型做的一层封装它非常灵活,支持自动扩容切片是一个引用类型,它的内部结构包含地址、长度和容量声明切片类型的基本语法如下&#…

qt-C++笔记之主线程中使用异步逻辑来处理ROS事件循环和Qt事件循环解决相互阻塞的问题

qt-C笔记之主线程中使用异步逻辑来处理ROS事件循环和异步循环解决相互阻塞的问题 code review! 文章目录 qt-C笔记之主线程中使用异步逻辑来处理ROS事件循环和异步循环解决相互阻塞的问题1.Qt的app.exec()详解2.ros::spin()详解3.ros::AsyncSpinner详解4.主线程中结合使用的示…

hyper-V操作虚拟机ubuntu 22.03

安装hyper-V 点击卸载程序 都勾选上即可 新建虚拟机,选择镜像文件 选择第一代即可 设置内存 配置网络 双击 启动安装虚拟机 输入用户名 zenglg 密码:LuoShuwen123456 按照enter键选中openssh安装 安装中 安装完成 选择重启 输入用户名、密码

Java进阶(第三期): JDK版本接口的新特性 内部类(成员类、静态类、局部类、匿名类) Lambda表达式、简写规则

Java进阶(第三期) ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ 文章目录 Java基础(第三期)一、接口新特性1.1 JDK8版本1.2 JDK9版本 代码块二、内部类1、成员内部类1.2 内部类成员访问 2、 静态内部类3、 局部…

Python三百行代码实现一简约个人博客网站(全网最小巧)

这是全互联网最小巧的博客,没有比这更小的了。虽然小巧,但功能一点儿也不弱,支持文章的分页展示,文章表格,图片和代码语法高亮。文章无限制分类,访问量统计,按时间和按点击量排序,展…

CPU虚拟化的过程

VMCS 是Virtual Machine Control Structure。是 Intel 实现 CPU 虚拟化,记录 vCPU 状态的一个关键数据结构。VMCS 数据结构主要包含以下信息。 Guest-state area,即 vCPU 的状态信息,包括 vCPU 的基本运行环境,例如寄存器等。Hos…

数据治理模型的三个模块

数据接入模块 大数据工程的数据来源包含企业内部数据和企业外部数据,其中企业内部数据由资源服务平台、综合资源库、各业务系统生产库中的结构化数据和文件服务器上的文本、图片等非结构化数据组成,其中包括人财物记录、财物报表、原材料、顾客信息、气…

启动kafka集群以及关闭

kafka操作 第一个窗口 cd /root/software/kafka bin/zookeeper-server-start.sh config/zookeeper.properties最后这种就是成功了 Zookeeper 启动: Zookeeper 是 Kafka 集群的协调服务,启动 Kafka 之前必须确保 Zookeeper 正在运行。 第二个窗口&am…

谨慎Apache-Zookeeper-3.5.5以后在CentOS7.X安装的坑

目录 前言 一、现场还原 二、问题诊断 三、问题原因 总结 前言 最近由于项目需要,在服务器上需要搭建Hbase完全分布式集群环境。开发环境,采用的是最小节点的方式进行搭建(即3个节点的模式)。资源环境列表如下: 序号…

CentOS7搭建Kubernetes集群

环境准备:配置好静态IP地址的Centos7(2核、master内存3GB、slave内存2GB)。 搭建概述:先将一台虚拟机搭建为master、随后克隆出两台虚拟机作为从节点。 虚拟机主机名和IP地址: 主机名IP地址master192.168.138.110sl…

python类的多重继承继承和查找顺序

1 python类的多重继承继承和查找顺序 python中,类的多重继承允许子类继承多个基类,子类可以访问多个基类的属性和方法。 1.1 多重继承基础 用法 class MulClass(BaseC1,BaseC2,...BaseCn):pass描述 Mulclass:子类(或者称混合…

网络核心知识总结

计算机网络总结 基础 网络分层模型 OSI 七层模型是什么?每一层的作用是什么? OSI 体系结构是法律上的国家标准,从上往下讲分别是: 应用层 – 作用是 – 为计算机用户提供服务表示层 – 作用是 – 数据处理(编解码、加密解密、…

【数据结构】八大排序 (三)

目录 前言: 快速排序 快速排序非递归实现 快速排序特性总结 归并排序 归并排序的代码实现 归并排序的特性总结 计数排序 计数排序的代码实现 计数排序的特性总结 前言: 前文快速排序采用了递归实现,而递归会开辟函数栈帧&#xff0…

赴日开发做什么?日本签证很难拿?

日本的IT行业历史比较悠久,业务以上层前端业务为主,如设计和构建软件。日本IT公司组织庞大,行业内部有着严格的分工和部署,工作会被细分化。分配给个人的工作量不会太大,难度也不会很高。 在日本IT公司就业&#xff0…