服务限流

项目: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;}
}

【组件】接口限流与接口计次组件相关推荐

  1. Spring Cloud Alibaba基础教程:使用Sentinel实现接口限流

    点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 最近管点闲事浪费了不少时间,感谢网友们的留言提醒. 及时纠正路线,继续跟大家一起学习Spring Cl ...

  2. Gateway配合sentinel自定义限流_你知道如何使用阿里Sentinel实现接口限流吗?

    Nacos作为注册中心和配置中心的基础教程,到这里先告一段落,后续与其他结合的内容等讲到的时候再一起拿出来说,不然内容会有点跳跃.接下来我们就来一起学习一下Spring Cloud Alibaba下的 ...

  3. 天弘基金首席架构师李鑫:微服务接口限流的算法及架构实现

    李鑫(码码的土狼) 读完需要 9 分钟 速读仅需 3 分钟 李鑫,著有<微服务治理:体系.架构及实践>一书,公众号"码码的土狼"分享技术干货及心得. 目前是天弘基金移动 ...

  4. 14 基于网关Spring Cloud Zuul的接口限流实现方案

    在Spring Cloud Zuul网关中,限流业务是放在前置过滤器实现的,也就是在请求被Zuul转发给微服务之前进行限流.另外,当前置过滤器中同时存在限流.鉴权.身份认证等业务时,应该将限流业务放在 ...

  5. 轻松两步,我在 SpringBoot 服务上实现了接口限流

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! Sentinel是阿里巴巴开源的限流器熔断器,并且带有可视 ...

  6. 亿级流量场景下如何为HTTP接口限流?看完我懂了!!

    这里,我们实现Web接口限流,具体方式为:使用自定义注解封装基于令牌桶限流算法实现接口限流. 不使用注解实现接口限流 搭建项目 这里,我们使用SpringBoot项目来搭建Http接口限流项目,Spr ...

  7. 微服务接口限流的设计与思考(附GitHub框架源码)

    http://www.infoq.com/cn/articles/microservice-interface-rate-limit?useSponsorshipSuggestions=true&am ...

  8. 后端技术:阿里开源的接口限流神器Sentinel介绍

    Sentinel是阿里巴巴开源的限流器熔断器,并且带有可视化操作界面. 在日常开发中,限流功能时常被使用,用于对某些接口进行限流熔断,譬如限制单位时间内接口访问次数:或者按照某种规则进行限流,如限制i ...

  9. java 接口防刷_java轻量级接口限流/防刷插件

    简介 call-limit提供接口限流.防刷的功能,插件基于spring开发,在应用应用的任何一个逻辑层皆可使用(web.service.dao), 插件支持单机应用下的限流和分布式应用的限流(分布式 ...

最新文章

  1. 独家 | 探索性文本数据分析的新手教程(Amazon案例研究)
  2. CSS浏览器兼容性问题详解总结
  3. webpack4打包工具
  4. 初学者的React全家桶完整实例
  5. linux 网络管理
  6. 从Java到C++——常量的使用规则
  7. 六种方法帮你解决模型过拟合问题
  8. 如何在苹果Mac中使用“启动安全性实用工具”?
  9. WPF 重定向DLL stdout
  10. 八大排序算法的时间、空间复杂度和稳定性
  11. JAVAJSP校园宿舍报修系统JSP宿舍管理系统JSP宿舍报修管理系统JSP学生公寓管理系统
  12. verilog 分频器设计(奇偶分频、半整数分频、任意分频、任意占空比)
  13. C#开发WinForm之DataGridView开发
  14. Datawhale来到2050!
  15. 浏览器会不会缓存html,浏览器缓存机制(一)
  16. 寒假的时候,小明同学要去拜访很多朋友,恰巧他所有朋友的家都处在坐标平面的X轴上。小明可以任意选择一个朋友的家开始访问,但是每次访问后他都必须回到出发点,然后才能去访问下一个朋友。
  17. 千万要找一个程序员谈恋爱!
  18. oracle 加密成,Oracle wrap加密 和 unwrap解密过程!
  19. 自己创作的一个简单的蠕虫病毒
  20. case study--marketing entry(附详尽分析) ※ 来源: 同济网论坛 BBS.TONGJI.NET

热门文章

  1. 世纪安图三区三线质检解决方案
  2. Fsl学习过程(一)
  3. 洛谷P4088 [USACO18FEB]Slingshot
  4. FilterDispatcher已被标注为过时解决办法 gt;gt;gt; FilterDispatcher lt;lt;lt; is deprecated!...
  5. iPhone天价维修费被指暴利:按键进水要上千元
  6. C#怎样处理一个panel的显示隐藏
  7. JavaScript标准日期、中国标准时间、时间戳、毫秒数互转
  8. el-table后端返回日期2023-04-07T09:10:47.000+00:00格式转换
  9. Excel催化剂开源第32波-VSTO开发的插件让WPS顺利调用的方法-注册表增加注册信息...
  10. C++Python描述 LeetCode 551. 学生出勤记录 I