基于令牌桶算法实现的SpringBoot分布式无锁限流插件
本文档不会是最新的,最新的请看Github!

1.简介
基于令牌桶算法和漏桶算法实现的纳秒级分布式无锁限流插件,完美嵌入SpringBoot、SpringCloud应用,支持接口限流、方法限流、系统限流、IP限流、用户限流等规则,支持设置系统启动保护时间(保护时间内不允许访问),提供快速失败与CAS阻塞两种限流方案,开箱即用。

2.Maven
<dependency>
<groupId>cn.yueshutong</groupId>
<artifactId>spring-boot-starter-current-limiting</artifactId>
<version>0.0.x.RELEASE</version>
</dependency>
3.方法限流
在需要限流的方法上使用 @CurrentLimiter 注解,不局限于Controller方法,示例代码如下:
@RestController
public class MyController {
@RequestMapping("/hello")
@CurrentLimiter(QPS = 2)
public String hello(){
return "hello";
}
}
@CurrentLimiter 注解参数说明:
| 属性 | 说明 | 默认值 |
|---|---|---|
| QPS | 每秒并发量 | 20 |
| initialDelay | 初始延迟时间 | 0 |
| failFast | 是否快速失败 | true |
| overflow | 是否严控速率 | false |
关于属性的具体说明请参见下方介绍。
4.系统限流
对整个应用的限流只需要在配置文件中配置即可,示例代码如下:
current.limiting.enabled=true #开启系统限流
current.limiting.part-enabled=false #使限流注解的作用失效
current.limiting.qps=100 #每秒并发量,支持小数、分数。计算规则:次数/时间(秒级)
current.limiting.fail-fast=true #快速失败
current.limiting.initial-delay=0 #系统启动保护时间为0
current.limiting.overflow=true #切换为漏桶算法
参数说明:
| 属性 | 说明 | 默认值 |
|---|---|---|
| enabled | 是否开启非注解的限流器 | FALSE |
| part-enabled | 是否开启注解限流的作用。FALSE可使注解限流失效 | TRUE |
| qps | 每秒并发量。支持小数、分数,计算规则:次数/时间(秒级),为0禁止访问 | 100 |
| fail-fast | 是否执行快速失败,FALSE可切换为阻塞 | TRUE |
| initial-delay | 首次放入令牌(即允许访问)的延迟时间,可作为系统启动保护,单位:毫秒 | 0 |
| overflow | 是否严格控制请求速率和次数,TRUE即切换为漏桶算法 | false |
5.拒绝策略
提供快速失败与CAS阻塞两种限流方案。如果是阻塞则不需要拒绝策略,当获取到令牌后依旧会继续执行,可以当做一种限制速率的措施。这里只讨论快速失败的拒绝策略。
快速失败的默认策略是统一返回“服务不可用”的英文说明文字,如果用户需要自定义拒绝策略,提供两种接口供实现。
针对被注解的方法进行自定义拒绝策略是实现CurrentAspectHandler接口,示例代码:
@Component
public class MyAspectHandler implements CurrentAspectHandler {
@Override
public Object around(ProceedingJoinPoint pjp, CurrentLimiter rateLimiter) throws Throwable {
//被注解修饰的方法返回值,慎用!
//可以结合Controller返回自定义视图
return "fail";
}
}
针对系统级别的拒绝策略是实现CurrentInterceptorHandler接口,示例代码:
@Component
public class MyInterceptorHandler implements CurrentInterceptorHandler {
@Override
public void preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.getWriter().print("fail");
}
}
需要注意的是,以上实现类在Application中只能注入一个。
6.集群限流
集群限流的目的是对相同实例(即ApplicationName)的集群进行统一的限流,前提是已经开启并配置好Redis,直接开启即可:
spring.redis.host=127.0.0.1
spring.redis.password=
spring.redis.port=6379
#一行开启
current.limiting.cloud-enabled=true
例如QPS为2,两个实例组成集群,效果图如下:


7.自定义限流规则
在实际场景中,我们的限流规则并不只是简单的对整个系统或单个接口进行流控,需要考虑的是更复杂的场景。例如:
- 对请求的目标URL进行限流(例如:某个URL每分钟只允许调用多少次)
- 对客户端的访问IP进行限流(例如:某个IP每分钟只允许请求多少次)
- 对某些特定用户或者用户组进行限流(例如:非VIP用户限制每分钟只允许调用100次某个API等)
- 多维度混合的限流。此时,就需要实现一些限流规则的编排机制。与、或、非等关系。
在本插件中实现这些业务需求是非常轻量简便的,只需要一个实现 CurrentRuleHandler 接口并返回CurrentProperty 对象的 Bean 即可。示例代码如下:
@Component
public class MyRule implements CurrentRuleHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
public CurrentProperty rule(HttpServletRequest request) {
request.getServletPath(); // /hello
request.getMethod(); // GET
request.getRemoteHost(); // 127.0.0.1
request.getSession(); // session
return new CurrentProperty("Default",3,0,true,true);
}
}
CurrentProperty 构造方法参数说明:
| 参数 | 说明 |
|---|---|
| id | 标识名。若为IP地址则为IP地址限流,若为用户名则为用户限流,若为访问的URL则为接口限流。 |
| qps | 每秒并发量。支持小数、分数,计算规则:次数/时间(秒)。为0禁止访问。 |
| initialDelay | 首次放入令牌(即允许访问)延迟时间,可作为系统启动保护时间,单位/毫秒。 |
| failFast | 是否需开启快速失败。false即切换为阻塞。 |
| overflow | 是否严格控制请求速率和次数,true即切换为漏桶算法。 |
例如:对接口进行限流,只需要 request.getServletPath() 作为参数 id 的值即可。
8.关于作者
Github:https://github.com/yueshutong/spring-boot-starter-current-limiting
Gitee:https://gitee.com/zyzpp/spring-boot-starter-current-limiting
交流QQ群:781927207
基于令牌桶算法实现的SpringBoot分布式无锁限流插件的更多相关文章
- coding++:RateLimiter 限流算法之漏桶算法、令牌桶算法--简介
RateLimiter是Guava的concurrent包下的一个用于限制访问频率的类 <dependency> <groupId>com.google.guava</g ...
- php 基于redis使用令牌桶算法 计数器 漏桶算法 实现流量控制
通常在高并发和大流量的情况下,一般限流是必须的.为了保证服务器正常的压力.那我们就聊一下几种限流的算法. 计数器计数器是一种最常用的一种方法,在一段时间间隔内,处理请求的数量固定的,超的就不做处理. ...
- RateLimiter令牌桶算法
限流,是服务或者应用对自身保护的一种手段,通过限制或者拒绝调用方的流量,来保证自身的负载. 常用的限流算法有两种:漏桶算法和令牌桶算法 漏桶算法 思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度 ...
- 使用Redis实现令牌桶算法
在限流算法中有一种令牌桶算法,该算法可以应对短暂的突发流量,这对于现实环境中流量不怎么均匀的情况特别有用,不会频繁的触发限流,对调用方比较友好. 例如,当前限制10qps,大多数情况下不会超过此数量, ...
- 限流10万QPS、跨域、过滤器、令牌桶算法-网关Gateway内容都在这儿
一.微服务网关Spring Cloud Gateway 1.1 导引 文中内容包含:微服务网关限流10万QPS.跨域.过滤器.令牌桶算法. 在构建微服务系统中,必不可少的技术就是网关了,从早期的Zuu ...
- 15行python代码,帮你理解令牌桶算法
本文转载自: http://www.tuicool.com/articles/aEBNRnU 在网络中传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送,令牌桶算法 ...
- flask结合令牌桶算法实现上传和下载速度限制
限流.限速: 1.针对flask的单个路由进行限流,主要场景是上传文件和下载文件的场景 2.针对整个应用进行限流,方法:利用nginx网关做限流 本文针对第一中情况,利用令牌桶算法实现: 这个方法:h ...
- 令牌桶算法实现API限流
令牌桶算法( Token Bucket )和 Leaky Bucket 效果一样但方向相反的算法,更加容易理解.随着时间流逝,系统会按恒定 1/QPS 时间间隔(如果 QPS=100 ,则间隔是 10 ...
- coding++:Semaphore—RateLimiter-漏桶算法-令牌桶算法
java中对于生产者消费者模型,或者小米手机营销 1分钟卖多少台手机等都存在限流的思想在里面. 关于限流 目前存在两大类,从线程个数(jdk1.5 Semaphore)和RateLimiter速率(g ...
随机推荐
- 不可思议的纯 CSS 实现鼠标跟随效果
直接进入正题,鼠标跟随,顾名思义,就是元素会跟随着鼠标的移动而作出相应的运动.大概类似于这样: 通常而言,CSS 负责表现,JavaScript 负责行为.而鼠标跟随这种效果属于行为,要实现通常都需要 ...
- Java面试题:Java中怎么样实现多线程
方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 run() ,加入线程所要执行的代码即可. 下面是一个例子: public class MyThrea ...
- Oracle权限授予
一.用户 sys;//系统管理员,拥有最高权限 system;//本地管理员,次高权限 scott;//普通用户,密码默认为tiger,默认未解锁 二.登陆 sqlplus / as sysdba;/ ...
- Vue(day8)
继续上一篇文章的内容,本文主要内容为项目中新闻资讯模块的实现. 新闻资讯页面主要是当我们点击这个按钮时跳转到新闻列表界面. 一.新闻资讯的路由设计 将新闻资讯的标签改为路由:(a标签改为router- ...
- shell脚本获取进程ID并杀死的实现及问题解析
经常需要杀死某个进程,操作了几次之后,对一个熟练的码农来说,就要制作自己的工具了.有些工具虽然很小,但是却能节省一大部分的时间. 输入某个进程的ID并杀死的方法.这种事情,一般是先搜索再进行优化,这种 ...
- RIpng配置(GNS3)(第九组)
一.拓扑图 二.路由器配置 路由器R1的配置(配置RIP静态路由协议,路由器对应接口配置相对应的ipv6地址,并给每个接口配置RIP 1 enable) 路由器R2的配置(配置RIP静态路由协议,路由 ...
- .NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐
作者:依乐祝 原本链接:https://www.cnblogs.com/yilezhu/p/9947905.html 引子 为什么写这篇文章呢?因为.NET Core的生态越来越好了!之前玩转.net ...
- 移动APP及游戏推广,有预算为什么还起不了量
本文转自公众号:caoz的梦呓,作者是互联网行业内资深人士,这里分享一篇他本人写的经验干货,希望能给大家带来点帮助. 在广告分析师群,起量是他们讨论最多的话题之一. 我们刚做游戏出海业务的时候,第一款 ...
- .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了
最近有个需求就是一个抽象仓储层接口方法需要SqlServer以及Oracle两种实现方式,为了灵活我在依赖注入的时候把这两种实现都给注入进了依赖注入容器中,但是在服务调用的时候总是获取到最后注入的那个 ...
- nodejs 开发企业微信第三方应用入门教程
最近公司要开发企业微信端的 Worktile,以前做的是企业微信内部应用,所以只适用于私有部署客户,而对于公有云客户就无法使用,所有就准备开发企业微信的第三方应用,本文主要介绍在调研阶段遇到的山珍海味 ...