Redis接口访问优化

说明:之前写过一篇使用Redis接口访问的博客,如下。最近有相关需求,把代码拿出来后,做了一些优化,挺有意思的,本文介绍在原基础上

  • 使用Redis实现接口防抖

优化

总的来说,这次使用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();/*** 时间段* @return*/int duration();
}

(切面,实现限制访问)

import com.hezy.annotation.LimitAccess;
import lombok.extern.log4j.Log4j2;
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.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;/*** AOP类(通知类)*/
@Component
@Aspect
@Log4j2
public class LimitAspect {@Value("${access.enable:false}")private boolean enable;@Autowiredprivate RedisTemplate redisTemplate;@Pointcut("@annotation(com.hezy.annotation.LimitAccess)")public void pt(){};@Around("pt()")public Object aopAround(ProceedingJoinPoint pjp) throws Throwable {// 设置一个开关,控制是否执行if (!enable) {return pjp.proceed();}// 获取切入点上面的自定义注解Signature signature = pjp.getSignature();MethodSignature methodSignature = (MethodSignature) signature;// 获取方法上面的注解LimitAccess limitAccess = methodSignature.getMethod().getAnnotation(LimitAccess.class);// 获取注解上面的属性值int limit = limitAccess.times();String key = limitAccess.key();int duration = limitAccess.duration();// 递增键的值,如果键不存在则初始化为1Long currentCount = redisTemplate.opsForValue().increment(key, 1);// 如果键是新创建的,设置过期时间if (currentCount != null && currentCount == 1) {redisTemplate.expire(key, duration, TimeUnit.SECONDS);}// 检查是否超过限制if (currentCount != null && currentCount > limit) {log.info("访问过于频繁: " + pjp.toLongString());throw new RuntimeException("访问过于频繁");}return pjp.proceed();}
}

(使用,在对应的接口上,打上注解,填上数值,如下表示,1秒内不能访问超过3次)

    @LimitAccess(key = "test", times = 3, duration = 1)@GetMappingpublic String test() {return demoService.test();}

另外,在代码中加了一个开关,可在配置文件中设置此配置,表示开启或者关闭,默认是关闭的

access:enable: true

启动项目,测试一下

在这里插入图片描述

思考

以上代码,有两点需要思考:

  • 注解能不能加在Service层的方法上,加了有没有用?另外加了会不会让声明式事务失效?

  • 这个限制,没有到用户的维度,也就是说所有的用户,只要在一个时间段内访问超过次数就限制,这显然是不行的。有什么办法吗?

第一点,我测试过,注解可以加在Service层方法上,是可以的,不会让事务失效,如下:

    @LimitAccess(key = "deleteUserById", times = 3, duration = 1)@Transactional@Overridepublic void deleteUserById(Integer id) {// 删除用户userMapper.deleteUserById(id);int i = 1 / 0;// 删除用户对应的角色userMapper.deleteUserRoleMapper(id);}

接口限制,事务,都生效了。

第二点,这确实是个问题,要做到针对用户层面的接口限制是必须的,不然有一个用户恶意刷新,其他用户都用不了了,这怎么可以。要解决这个问题,首先要拿到当前操作用的标识,用户名、用户ID,然后再存入key的时候,拼接上这个标识作为key。

	String key = limitAccess.key() + 用户标识(用户名、用户id);

获取当前用户信息,参考下面这篇文章:

  • 获取当前用户信息的几种方式

如果你不是自己从0开发项目,一般成熟的项目都会有获取当前操作用户信息的方式的。实在不行,你让前端把用户id作为参数传给你,你在切面里获取这个用户id都可以。

总结

本文是对之前用Redis接口访问的优化,以及对两个问题的考虑,希望能对大家有启发。

获取源码:https://github.com/HeZhongYing/limit_access_demo

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

操作系统 | 学习笔记 | 王道 | 4.1 文件系统基础

4.文件管理 4.1 文件系统基础 4.1.1 文件的基本概念 定义 文件是以计算机硬盘为载体的存储在计算机上的信息集合,在用户进行的输入、输出中,以文件位基本单位。 文件管理系统是实现的文件的访问、修改和保存,对文件维护管理的系统。 文件的…

2024重生之回溯数据结构与算法系列学习(11)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】

欢迎各位彦祖与热巴畅游本人专栏与博客 你的三连是我最大的动力 以下图片仅代表专栏特色 [点击箭头指向的专栏名即可闪现] 专栏跑道一 ➡️ MYSQL REDIS Advance operation 专栏跑道二➡️ 24 Network Security -LJS ​ ​ ​ 专栏跑道三 ➡️HCIP;H3C-SE;CCIP——…

APP自动化搭建与应用

APP自动化环境搭建 用于做APP端UI自动化,adb连接手机设备。 需要的工具java编辑器:jdk、Android-sdk软件开发工具组、appium的python客户端、nodes.js、夜神模拟器、apk包、uiautomatorviewer 第一步:安装sdk,里面包含建立工具bu…

一、机器学习算法与实践_06迭代法和KMeans、线性回归、逻辑回归算法笔记

0 迭代法 迭代法不仅是机器学习、深度学习的核心,也是整个人工智能领域的重要概念,其对于算法的设计和实现至关重要 0.1 适合场景 对于不能一次搞定的问题,将其分成多步来解决,逐步逼近解决方案 0.2 典型应用 KMeans 聚类算法…

9-贪心算法

PDF文档下载:LeetCode-贪心算法-java 参考:代码随想录 题目分类大纲如下: 贪心算法理论基础 什么是贪心? 贪心的本质是选择每一阶段的局部最优,从而达到全局最优。 贪心的套路(什么时候用贪心&#xff…

计算机网络——http和web

无状态服务器——不维护客户端 怎么变成有状态连接 所以此时本地建立代理—— 若本地缓存了——但是服务器变了——怎么办?

Pikachu-File Inclusion-远程文件包含

远程文件包含漏洞 是指能够包含远程服务器上的文件并执行。由于远程服务器的文件是我们可控的,因此漏洞一旦存在,危害性会很大。但远程文件包含漏洞的利用条件较为苛刻;因此,在web应用系统的功能设计上尽量不要让前端用户直接传变…

用java编写飞机大战

游戏界面使用JFrame和JPanel构建。背景图通过BG类绘制。英雄机和敌机在界面上显示并移动。子弹从英雄机发射并在屏幕上移动。游戏有四种状态:READY、RUNNING、PAUSE、GAMEOVER。状态通过鼠标点击进行切换:点击开始游戏(从READY变为RUNNING&am…

CSS | 响应式布局之媒体查询(media-query)详解

media type(媒体类型)是CSS 2中的一个非常有用的属性,通过media type我们可以对不同的设备指定特定的样式,从而实现更丰富的界面。media query(媒体查询)是对media type的一种增强,是CSS 3的重要内容之一。随着移动互联网的发展,m…

reactNative本地调试localhost踩坑

本地调试请求localhost的时候 1.要和电脑处在同一局域网下面(同一个wifi) 2.把baseURL的localhost改成命令行中ipconfig查询到的IPv4 地址 . . . . . . . . . . . . : (例如)192.168.1.103 如果报错Net Work Error,可…

BMC pam认证的使用

1.说明 1.1 文档参考资料 https://www.chiark.greenend.org.uk/doc/libpam-doc/html/Linux-PAM_ADG.htmlhttp://www.fifi.org/doc/libpam-doc/html/pam_appl-3.htmlpdf文档: https://fossies.org/linux/Linux-PAM-docs/doc/adg/Linux-PAM_ADG.pdflinux-pam 中文文档pam 旧文p…

Redis基础二(spring整合redis)

Springboot整合Redis 一、Springboot整合redis ​ redis可以通过使用java代码来实现 第一部分文档中 在终端操作redis的所有命令,Spring已经帮我们封装了所有的操作,所以变得很简单了。 ​ Spring专门提供了一个模块来进行这些操作的封装,这…

【Linux】详解Linux下的工具(内含yum指令和vim指令)

文章目录 前言1. Linux下软件安装的方式2. yum2.1 软件下载的小知识2.2 在自己的Linux系统下验证yum源的存在2.3 利用yum指令下载软件2.4 拓展yum源(针对于虚拟机用户) 3. vim编辑器3.1 vim是什么?3.2 如何打开vim3.2 vim各模式下的讲解3.2.1…

Oracle中ADD_MONTHS()函数详解

文章目录 前言一、ADD_MONTHS()的语法二、主要用途三、测试用例总结 前言 在Oracle数据库中,ADD_MONTHS()函数用于在日期中添加指定的月数。 一、ADD_MONTHS()的语法 ADD_MONTHS(date, n) 其中,date是一个日期值,n是一个整数值&#xff0c…

基于vue框架的大学生学业预警系统设计与实现53ify(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能:学生,公告信息,成绩信息,科目,学分信息,考勤信息,教师 开题报告内容 基于Vue框架的大学生学业预警系统设计与实现开题报告 一、研究背景与意义 随着高等教育的普及与深入,大学生群体规模日益扩大,其学业管理成…

百元头戴式耳机哪款口碑爆棚+质价比高?2024耳机最强推荐攻略!

在2024年的耳机市场中,百元头戴式耳机凭借其亲民的价格和出色的性能,成为了众多消费者的首选。随着技术的不断进步,这一价位段的耳机不仅在音质上有了显著提升,还在舒适度、降噪能力以及续航时间等方面表现出色。那百元头戴式耳机…

CAN XL协议标准在CANoe中的应用

众所周知,CAN通信技术在汽车领域中,有着非常广泛的应用。从1991年,第一代经典CAN在奔驰S级轿车中首次应用;到2011年,开始第二代CAN总线(即CAN FD)的开发;如今,ISO 11898-…

MyBatis 操作数据库入门

目录 前言 1.创建springboot⼯程 2.数据准备 3.配置Mybatis数据库连接信息 4.编写SQL语句,进行测试 前言 什么是MyBatis? MyBatis是⼀款优秀的 持久层 框架,⽤于简化JDBC的开发 Mybatis操作数据库的入门步骤: 1.创建springboot⼯程 2.数…

kwin- 插件加载绘制流程

1. 配置文件的作用具体是做什么的? 相当于用户强制设置了特效的开关,对于没有写在配置文件里的特效,会检测默认加载值,确定是否加载。写在了文件里的会根据返回的值,来加载特效。 2. 为什么配置文件没有写&#xff0c…

【自用】王道文件管理强化笔记

文章目录 操作系统引导:磁盘初始化文件打开过程角度1文件的打开过程角度2 内存映射的文件访问 操作系统引导: ①CPU从一个特定主存地址开始,取指令,执行ROM中的引导程序(先进行硬件自检,再开机) ②)将磁盘的第一块–主引导记录读入内存&…