【组件】接口限流与接口计次组件
服务限流
项目:https://github.com/xuzhou-99/currentLimiting
前言
本模块主要实现对服务请求的限流,通过策略模式加载不同配置类型的限流实现,目前的限流算法是固定窗口限流算法(计数器)
,
一定时间内达到限流上限则限制访问。
主要的限流算法
参考文档:
4种经典限流算法讲解 https://zhuanlan.zhihu.com/p/376564740
架构之高并发:限流 https://www.pdai.tech/md/arch/arch-y-ratelimit.html
- 固定窗口限流算法
- 滑动窗口限流算法
- 漏桶算法
- 令牌桶算法
主要模块
- 限流实现:
- 注解限流:
@CurrentLimiting
,通过注解添加限流场景、策略、限流上限等参数 - 动态限流:
LimitFilter
,通过其中的静态方法,动态添加、删除、查看、初始化限流请求
- 注解限流:
- 限流场景
SceneStrategy
:全局限流、IP限流 - 限流计数器
CountStrategy
:本地缓存、Redis(单机) - 限流策略
LimitingStrategy
:秒、分、时、天、周、月、年
引用组件
- 目前是发布在github个人仓库,引用时需要添加 github 仓库
<repositories><!-- github --><repository><id>github</id><!-- https://raw.github.com/用户名/仓库名/分支名 --><url>https://raw.github.com/xuzhou-99/mvn-repo/main</url><snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots></repository>
</repositories><dependencies><!--altaria 限流组件--><dependency><groupId>cn.altaria</groupId><artifactId>currentLimiting</artifactId><version>0.0.2-SNAPSHOT</version></dependency>
</dependencies>
配置参数
# ------------------------ 限流配置 ---------------------------- #
security:limit:# 限流是否开启enable: true# 限流计数器策略,支持cache(本地),rediscount-strategy: redisspring:# -------------- redis配置,如果想使用redis模式,则配置------------#redis:host: 127.0.0.1port: 6379
回调接口实现
提供回调接口 ILimitingInfoHandle
,实现其中的 callback()
方法,可以获取每次限流/计次信息,自由拓展功能,例如记录数据库日志。
- isSupport:默认需要2个实现类,分别支持
- “limit”.equals(type):该实现类支持所有的限流回调
- “times”.equals(type):该实现类仅支持计次回调
- doBefore:限流或计次前调用方法
- 计次需要特殊处理,实现该方法,获取appId、secretKey,进行判断是否有效,并处理计次有效时长、总次数
- callback:回调方法,可以实现进行数据库处理等操作
/*** @author xuzhou* @since 2022/11/14*/
public interface ILimitingInfoHandle {/*** 支持限流模式** @param type 限流模式:limit限流,times计次* @return 支持*/boolean isSupport(String type);/*** 校验 请求中 AppId和 SecretKey 是否有效** @param limitInfo 限流参数信息* @return 有效*/default boolean doBefore(LimitingPointInfo limitInfo) {return true;}/*** 回调处理** @param limitInfo 限流信息*/default void callback(LimitingPointInfo limitInfo) {// 计次通过后,剩余次数-1}}
使用示例
接口限流
注解限流
通过添加注解@CurrentLimiting
来标记该请求路由需要进行限流,切面CurrentLimitingAspect
拦截
统一处理,解析请求路径、请求IP,调用限流过滤器CurrentLimitingProcessor
根据配置中的count-strategy
来策略
加载限流计数器,可以选择本地缓存cache
,或者redis
来进行限流处理。
- strategy:限流策略
- strategyTime:限流策略组合时长,配合 currentLimiting.strategy().getExTime() 生成过期时间,单位秒
- scene:限流场景
- limit:限流上限
例如,采用了redis
限流计数器策略,则在redis
中存放以下记录,每次通过的请求会使得value
原子增1,
当达到limit
上限的时候,则抛出CurrentLimitingException
限流上限异常,组织请求的继续。
- key(拼接的限流key): limit:ip:/api/limit1:172.31.2.214:60:2
- value(已请求次数计数): 1
// 使用示例
@Slf4j
@Controller
@RequestMapping("/api")
public class TestController {@GetMapping("/limit")@ResponseBody@CurrentLimiting(strategy = LimitingStrategy.MONTH_STRATEGY, strategyTime = 1L, scene = SceneStrategy.ALL, limit = 10L)public String limit() {System.out.println("测试限流...");return null;}
}
动态限流
对于请求的限流可能并不是实时都要的,可能某一段时间是需要进行限流,所以添加了动态限流的组件,实现核心是CurrentLimitingFilter
,
这是一个全局过滤器,可以通过调用其中的静态方法来实现动态管理限流。
- filterCache:动态限流集合,存放所有需要进行限流的请求标识
- doFilter:
Filter
实现方法,对所有记录在filterCache
中的请求进行限流管理 - method:静态管理方法
- initFilterCache():初始化动态限流集合
- getFilterCache():获取动态限流集合
- addLimit(***):新增限流
- removeFilterKey(String key):移除限流
- removeFilterKey(SceneStrategy scene, String requestTag):移除限流
@Slf4j
@Controller
@RequestMapping("/api")
public class TestController {@GetMapping("/limit1")@ResponseBodypublic String limit1() {log.info("测试 Filter 限流...");return null;}@GetMapping("/add")@ResponseBodypublic String add(HttpServletRequest request) {log.info("添加 Filter 限流...");String limitKey = CurrentLimitingFilter.addLimit(LimitingStrategy.MINUTE_STRATEGY, SceneStrategy.IP, 1L,2, "/api/limit1");return "添加" + limitKey + "限流!";}@GetMapping("/remove")@ResponseBodypublic String remove(HttpServletRequest request) {log.info("移除 Filter 限流...");String limitKey = CurrentLimitingFilter.removeFilterKey(SceneStrategy.IP, "/api/limit1");return "移除" + limitKey + "限流!";}
}
接口计次
接口计次
通过添加注解@CurrentLimiting
来标记该请求路由需要进行计次,切面CurrentLimitingAspect
拦截
统一处理,解析请求路径、请求IP,调用限流过滤器TimesLimitingProcessor
根据配置中的count-strategy
来策略
加载限流计数器,可以选择本地缓存cache
,或者redis
来进行限流处理。
- scene:限流场景-APP
- strategy、strategyTime、limit:可以通过 回调接口实现:doBefore/callback 来从数据库获取并修改,从而实现高度动态自定义
计次请求:
支持AppId、ip组合计次
- appId:应用id,放置于请求头
- secretKey:应用密钥,放置于请求头
// 使用示例
@Slf4j
@Controller
@RequestMapping("/api")
public class TestController {@GetMapping("/times")@ResponseBody@CurrentLimiting(strategy = LimitingStrategy.MONTH_STRATEGY, strategyTime = 1L, scene = SceneStrategy.APP, limit = 10L)public String times() {System.out.println("测试计次...");return null;}
}
【组件】接口限流与接口计次组件相关推荐
- Spring Cloud Alibaba基础教程:使用Sentinel实现接口限流
点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 最近管点闲事浪费了不少时间,感谢网友们的留言提醒. 及时纠正路线,继续跟大家一起学习Spring Cl ...
- Gateway配合sentinel自定义限流_你知道如何使用阿里Sentinel实现接口限流吗?
Nacos作为注册中心和配置中心的基础教程,到这里先告一段落,后续与其他结合的内容等讲到的时候再一起拿出来说,不然内容会有点跳跃.接下来我们就来一起学习一下Spring Cloud Alibaba下的 ...
- 天弘基金首席架构师李鑫:微服务接口限流的算法及架构实现
李鑫(码码的土狼) 读完需要 9 分钟 速读仅需 3 分钟 李鑫,著有<微服务治理:体系.架构及实践>一书,公众号"码码的土狼"分享技术干货及心得. 目前是天弘基金移动 ...
- 14 基于网关Spring Cloud Zuul的接口限流实现方案
在Spring Cloud Zuul网关中,限流业务是放在前置过滤器实现的,也就是在请求被Zuul转发给微服务之前进行限流.另外,当前置过滤器中同时存在限流.鉴权.身份认证等业务时,应该将限流业务放在 ...
- 轻松两步,我在 SpringBoot 服务上实现了接口限流
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! Sentinel是阿里巴巴开源的限流器熔断器,并且带有可视 ...
- 亿级流量场景下如何为HTTP接口限流?看完我懂了!!
这里,我们实现Web接口限流,具体方式为:使用自定义注解封装基于令牌桶限流算法实现接口限流. 不使用注解实现接口限流 搭建项目 这里,我们使用SpringBoot项目来搭建Http接口限流项目,Spr ...
- 微服务接口限流的设计与思考(附GitHub框架源码)
http://www.infoq.com/cn/articles/microservice-interface-rate-limit?useSponsorshipSuggestions=true&am ...
- 后端技术:阿里开源的接口限流神器Sentinel介绍
Sentinel是阿里巴巴开源的限流器熔断器,并且带有可视化操作界面. 在日常开发中,限流功能时常被使用,用于对某些接口进行限流熔断,譬如限制单位时间内接口访问次数:或者按照某种规则进行限流,如限制i ...
- java 接口防刷_java轻量级接口限流/防刷插件
简介 call-limit提供接口限流.防刷的功能,插件基于spring开发,在应用应用的任何一个逻辑层皆可使用(web.service.dao), 插件支持单机应用下的限流和分布式应用的限流(分布式 ...
最新文章
- 独家 | 探索性文本数据分析的新手教程(Amazon案例研究)
- CSS浏览器兼容性问题详解总结
- webpack4打包工具
- 初学者的React全家桶完整实例
- linux 网络管理
- 从Java到C++——常量的使用规则
- 六种方法帮你解决模型过拟合问题
- 如何在苹果Mac中使用“启动安全性实用工具”?
- WPF 重定向DLL stdout
- 八大排序算法的时间、空间复杂度和稳定性
- JAVAJSP校园宿舍报修系统JSP宿舍管理系统JSP宿舍报修管理系统JSP学生公寓管理系统
- verilog 分频器设计(奇偶分频、半整数分频、任意分频、任意占空比)
- C#开发WinForm之DataGridView开发
- Datawhale来到2050!
- 浏览器会不会缓存html,浏览器缓存机制(一)
- 寒假的时候,小明同学要去拜访很多朋友,恰巧他所有朋友的家都处在坐标平面的X轴上。小明可以任意选择一个朋友的家开始访问,但是每次访问后他都必须回到出发点,然后才能去访问下一个朋友。
- 千万要找一个程序员谈恋爱!
- oracle 加密成,Oracle wrap加密 和 unwrap解密过程!
- 自己创作的一个简单的蠕虫病毒
- case study--marketing entry(附详尽分析) ※ 来源: 同济网论坛 BBS.TONGJI.NET
热门文章
- 世纪安图三区三线质检解决方案
- Fsl学习过程(一)
- 洛谷P4088 [USACO18FEB]Slingshot
- FilterDispatcher已被标注为过时解决办法 gt;gt;gt; FilterDispatcher lt;lt;lt; is deprecated!...
- iPhone天价维修费被指暴利:按键进水要上千元
- C#怎样处理一个panel的显示隐藏
- JavaScript标准日期、中国标准时间、时间戳、毫秒数互转
- el-table后端返回日期2023-04-07T09:10:47.000+00:00格式转换
- Excel催化剂开源第32波-VSTO开发的插件让WPS顺利调用的方法-注册表增加注册信息...
- C++Python描述 LeetCode 551. 学生出勤记录 I