spring boot3自定义注解+拦截器+Redis实现高并发接口限流

 

⛰️个人主页:     蒾酒

🔥系列专栏:《spring boot实战》

🌊山高路远,行路漫漫,终有归途


目录

写在前面

内容简介

实现思路

实现步骤

1.自定义限流注解

2.编写限流拦截器

3.注册拦截器

4.接口限流测试


写在前面

本文介绍了springboot开发后端服务中,高并发接口限流设计与实现,坚持看完相信对你有帮助。

同时欢迎订阅springboot系列专栏,持续分享spring boot的使用经验。

内容简介

本文介绍了一种使用自定义注解结合拦截器和redis实现接口限流方法。这种方法也是企业常用方法,是一种比较优雅的解决方案。

优点分析

  1. 灵活性和可定制性: 通过自定义注解和拦截器,可以根据具体的业务需求灵活定义限流规则,满足不同接口的限流需求。

  2. 性能优化: 使用Redis等高性能缓存数据库存储限流计数器,能够有效减轻应用程序的压力,提高系统的性能表现。

  3. 实时性和持久性: Redis具有较高的读写性能,可以实时更新限流计数器,并且数据持久化,保证限流规则的持久性。

  4. 分布式支持: 对于分布式系统,使用Redis等分布式缓存数据库可以方便地实现跨节点的限流策略和计数器共享,确保限流的准确性和一致性。

  5. 成熟稳定: 这种方法经过实践验证,在众多企业项目中得到广泛应用,被认为是一种成熟、稳定且可靠的解决方案。

实现思路

通过自定义一个注解标注需要进行限流的接口方法,通过拦截器对标记改注解的方法进行拦截处理

将同一ip访问同一接口的次数缓存到redis,拦截器中进行判断处理,达到访问阈值直接拒绝。

实现步骤

1.自定义限流注解

import java.lang.annotation.*;/*** @author mijiupro*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Inherited
@Documented
public @interface AccessLimit {int limit() default 10; // 限流阈值int seconds() default 60; // 时间窗口
}

2.编写限流拦截器

/*** 接口限流拦截器* @author mijiupro*/
@Slf4j
@Component
public class AccessLimitInterceptor implements HandlerInterceptor {private final StringRedisTemplate redisTemplate;public AccessLimitInterceptor(StringRedisTemplate redisTemplate) {this.redisTemplate = redisTemplate;}@Overridepublic boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler)  {if (!(handler instanceof HandlerMethod handlerMethod)) {return true;}Method method = handlerMethod.getMethod();AccessLimit accessLimit = method.getAnnotation(AccessLimit.class);// 若方法上没有AccessLimit注解,直接放行if (accessLimit == null) {return true;}int limit = accessLimit.limit();int seconds = accessLimit.seconds();String key = generateKey(request); // 生成限流key// 使用基本类型long接收计数值,并确保不会因自动装箱产生NullPointerExceptionLong countResult = redisTemplate.opsForValue().increment(key, 1);long currentCount = countResult != null ? countResult : 0;if (currentCount == 1) {// 如果是第一次访问,设置过期时间redisTemplate.expire(key, seconds, TimeUnit.SECONDS);log.debug("设置访问限制计数为1:{}", key);return true;}if (currentCount > limit) {log.error("访问超过限制:{}", key);throw new RateLimitException(ResultEnum.ACCESS_LIMIT_REACHED);}log.debug("访问限制计数递增:{}", key);return true;}private String generateKey(HttpServletRequest request) {// 组合key的方式可以根据实际业务需要调整,例如考虑方法名称、用户ID等return request.getRemoteAddr() + ":" + request.getContextPath() + ":" + request.getServletPath();}}

3.注册拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer {private final AccessLimitInterceptor accessLimitInterceptor;public WebConfig( AccessLimitInterceptor accessLimitInterceptor) {this.accessLimitInterceptor = accessLimitInterceptor;}@Overridepublic void addInterceptors(@NotNull InterceptorRegistry registry) {//添加上接口限流拦截器使之生效registry.addInterceptor(accessLimitInterceptor).order(0);}
}

4.接口限流测试

随便写个接口标记限流注解进行测试

这里使用swagger3进行测试:

Spring Boot3整合knife4j(swagger3)_springboot3 knife4j-CSDN博客文章浏览阅读2.1k次,点赞39次,收藏52次。Knife4j · 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j (xiaominfo.com)作者的使用的spring boot 3.2.2为当前最新版,所以依赖导入最新的knife4j 4.4.0。3.1 增强模式 | Knife4j (xiaominfo.com)好一个spring boot项目且版本为3X,项目可正常启动。快速开始 | Knife4j (xiaominfo.com)接下来配置以下接口文档的作者等信息。@Tag注解:标记接口类别。_springboot3 knife4jhttps://blog.csdn.net/qq_62262918/article/details/135761392?spm=1001.2014.3001.5502

    @GetMapping("/get-int")@AccessLimit( limit = 5,  seconds= 60)public Integer getInt() {return 1;}

前五次访问:

第六次访问:

写在最后

spring boot3自定义注解+拦截器+Redis实现高并发接口限流到这里就结束了,本文介绍了一种常见的实现方法。任何问题评论区或私信讨论,欢迎指正。

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

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

相关文章

sql中使用了in直接卡死

项目场景: 最近在做数据迁移的工作,会员库有200多万数据,组织机构有4万数据。要把这些数据迁移到新系统的数据库中,开发新系统之前完全没考虑过数据量。当数据导入之后,页面就各种报错。。。。。。。。。。。。。。。…

外包干了8天,技术退步明显.......

先说一下自己的情况,大专生,19年通过校招进入杭州某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能测…

【ZZULIOJ】1009: 求平均分(Java)

目录 题目描述 输入 输出 样例输入 Copy 样例输出 Copy code 题目描述 已知某位学生的数学、英语和计算机课程的成绩,求该生三门课程的平均分。 输入 输入三个整数,数据之间由空格隔开。 输出 输出占一行,包含一个实数&#xff0c…

Redis命令介绍

一、redis启动: 本地启动:redis-cli 远程启动:redis-cli -h host -p port -a password Redis 连接命令 1 AUTH password 验证密码是否正确 2 ECHO message 打印字符串 3 PING 查看服务是否运行 4 QUIT 关闭当前连接 5 SELECT index 切换…

2024.3.28abc晚训题解

VJ晚训网址点击传送晚训 A题 比较巧的输入方式就是循环n&#xff0c;内层套一个循环7 #include<bits/stdc.h> using namespace std; int main(){int n;cin>>n;for(int i1;i<n;i){int ans0;for(int j1;j<7;j){int x;cin>>x;ansansx; }cout<<ans…

JUC内容概述

复习概念 Sleep和Wait的区别 Sleep是Thread的静态方法&#xff0c;wait是Object的方法&#xff0c;任何对象实例都可以使用sleep不会释放锁&#xff0c;他也不需要占用锁&#xff0c;暂停。wait会释放锁&#xff0c;但是调用他的前提是线程占有锁他们都可以被Interrupted方法…

SQLite数据库文件损坏的可能几种情况(一)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;十三&#xff09; 下一篇&#xff1a;SQLite使用的临时文件&#xff08;二&#xff09; 概述 SQLite数据库具有很强的抗损坏能力。如果应用程序崩溃&#xff0c…

鸿蒙hdc使用指导

简介 hdc&#xff08;HarmonyOS Device Connector&#xff09;是HarmonyOS为开发人员提供的用于调试的命令行工具&#xff0c;通过该工具可以在windows/linux/mac系统上与真实设备或者模拟器进行交互。 环境准备 hdc工具通过HarmonyOS SDK获取&#xff0c;存放于SDK的toolch…

2024-3-28 市场情绪强修复

这一轮退潮负反馈都修复了&#xff0c; 艾艾精工 博信股份 安奈尔 永悦科技 大理药业 &#xff0c;高新发展 也补跌了&#xff0c;收尸队也干活了&#xff0c;情绪不修复不接力得最好写照。这轮周期 宁科生物 已经7板&#xff0c;已经追平了 博信股份7板&#xff0c;看明天溢…

Mac安装minio

Mac安装minio 本文介绍使用 mac 安装 MinIO。 所有软件安装优先参考官网&#xff1a;MinIO Object Storage for MacOS — MinIO Object Storage for MacOS #使用 brew 安装 minio brew install minio/stable/minio#找到 minio tong ~ $ brew list minio /opt/homebrew/Cella…

银行监管报送系统介绍(十二):非居民金融账户涉税信息报送

国家税务总局、财政部、中国人民银行、中国银行业监督管理委员会、中国证券监督管理委员会、国家金融监督管理总局2017年5月9日发布、2017年7月1日起施行的《非居民金融账户涉税信息尽职调查管理办法》。 一、《管理办法》出台的背景是什么&#xff1f;   受二十国集团&…

math模块篇(四)

文章目录 math.ldexp(x, i)math.modf(x)math.nextafter(x, y, steps1)math.perm(n, kNone)math.prod(iterable, *, start1) math.ldexp(x, i) math.ldexp(x, i) 是 Python 中 math 模块的一个函数&#xff0c;用于执行二进制标度操作。它接受两个参数&#xff1a;尾数&#xf…

【unity】如何汉化unity Hub

相信大家下载安装unity后看着满操作栏的英文&#xff0c;英文不好的小伙伴们会一头雾水。但是没关系你要记住你要怎么高速运转的机器进入中国&#xff0c;请记住我给出的原理&#xff0c;不懂不代表不会用啊。现在我们就来把编译器给进行汉化。 第一步&#xff1a;我们打开Uni…

【VTKExamples::Points】第十一期 RadiusOutlierRemoval

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例RadiusOutlierRemoval,并解析接口vtkRadiusOutlierRemoval,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的…

【消息队列开发】 实现 MqClientTests 类——测试客户端

文章目录 &#x1f343;前言&#x1f333;所需属性&#x1f334;BeforeEach&#x1f332;AfterEach&#x1f38d;API测试⭕总结 &#x1f343;前言 本次开发任务 测试客户端接口 &#x1f333;所需属性 所需要一共三个属性 BrokerServer&#xff1a;服务器 ConnectionFa…

考研数学|武忠祥学习包搭配《660》和《880》

一、660、880、三大计算简单分析 660题 这本题册具有高难度、综合度和深度&#xff0c;属于高质量的题材。我建议不要在基础阶段就着手解决其中的660题&#xff0c;因为这可能会影响你的信心。相反&#xff0c;你可以在基础阶段完成一轮学习后&#xff0c;将这些题目留到强化…

安泰ATA-2161高压放大器在生物传感器研究中的应用

生物传感器&#xff08;biosensor&#xff09;&#xff0c;是一种对生物物质敏感并将其浓度转换为电信号进行检测的仪器&#xff0c;它利用固定化生物成分或生物体作为敏感元件。生物传感器并不专指用于生物技术领域的传感器&#xff0c;它的应用领域还包括环境监测、医疗卫生和…

基于NBIOT的物联网工程实训系统设计与实现

基于NBIOT的物联网工程实训系统设计与实现 **摘要&#xff1a;**随着物联网技术的飞速发展&#xff0c;窄带物联网&#xff08;NB-IoT&#xff09;作为其重要分支&#xff0c;在低功耗广域网络通信领域扮演着越来越重要的角色。本文旨在设计并实现一套基于NB-IoT的物联网工程实…

市场复盘总结 20240328

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 40% 最常用的…

MySQL 索引:索引为什么使用 B+树?

Hash 索引不支持顺序和范围查询&#xff1b; 二叉查找树(BST)&#xff1a;解决了排序的问题&#xff0c;极端情况下可能会退化成线性链表&#xff0c;查询效率急剧下降&#xff1b; 平衡二叉树(AVL) &#xff1a;通过旋转解决了平衡的问题&#xff0c;但是旋转操作效率太低&am…