本文档不会是最新的,最新的请看Github!

1.简介

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

2.Maven

  1. <dependency>
  2. <groupId>cn.yueshutong</groupId>
  3. <artifactId>spring-boot-starter-current-limiting</artifactId>
  4. <version>0.0.x.RELEASE</version>
  5. </dependency>

3.方法限流

在需要限流的方法上使用 @CurrentLimiter 注解,不局限于Controller方法,示例代码如下:

  1. @RestController
  2. public class MyController {
  3. @RequestMapping("/hello")
  4. @CurrentLimiter(QPS = 2)
  5. public String hello(){
  6. return "hello";
  7. }
  8. }

@CurrentLimiter 注解参数说明:

属性 说明 默认值
QPS 每秒并发量 20
initialDelay 初始延迟时间 0
failFast 是否快速失败 true
overflow 是否严控速率 false

关于属性的具体说明请参见下方介绍。

4.系统限流

对整个应用的限流只需要在配置文件中配置即可,示例代码如下:

  1. current.limiting.enabled=true #开启系统限流
  2. current.limiting.part-enabled=false #使限流注解的作用失效
  3. current.limiting.qps=100 #每秒并发量,支持小数、分数。计算规则:次数/时间(秒级)
  4. current.limiting.fail-fast=true #快速失败
  5. current.limiting.initial-delay=0 #系统启动保护时间为0
  6. 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接口,示例代码:

  1. @Component
  2. public class MyAspectHandler implements CurrentAspectHandler {
  3. @Override
  4. public Object around(ProceedingJoinPoint pjp, CurrentLimiter rateLimiter) throws Throwable {
  5. //被注解修饰的方法返回值,慎用!
  6. //可以结合Controller返回自定义视图
  7. return "fail";
  8. }
  9. }

针对系统级别的拒绝策略是实现CurrentInterceptorHandler接口,示例代码:

  1. @Component
  2. public class MyInterceptorHandler implements CurrentInterceptorHandler {
  3. @Override
  4. public void preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  5. response.getWriter().print("fail");
  6. }
  7. }

需要注意的是,以上实现类在Application中只能注入一个。

6.集群限流

集群限流的目的是对相同实例(即ApplicationName)的集群进行统一的限流,前提是已经开启并配置好Redis,直接开启即可:

  1. spring.redis.host=127.0.0.1
  2. spring.redis.password=
  3. spring.redis.port=6379
  4. #一行开启
  5. current.limiting.cloud-enabled=true

例如QPS为2,两个实例组成集群,效果图如下:

7.自定义限流规则

在实际场景中,我们的限流规则并不只是简单的对整个系统或单个接口进行流控,需要考虑的是更复杂的场景。例如:

  1. 对请求的目标URL进行限流(例如:某个URL每分钟只允许调用多少次)
  2. 对客户端的访问IP进行限流(例如:某个IP每分钟只允许请求多少次)
  3. 对某些特定用户或者用户组进行限流(例如:非VIP用户限制每分钟只允许调用100次某个API等)
  4. 多维度混合的限流。此时,就需要实现一些限流规则的编排机制。与、或、非等关系。

在本插件中实现这些业务需求是非常轻量简便的,只需要一个实现 CurrentRuleHandler 接口并返回CurrentProperty 对象的 Bean 即可。示例代码如下:

  1. @Component
  2. public class MyRule implements CurrentRuleHandler {
  3. private Logger logger = LoggerFactory.getLogger(getClass());
  4. @Override
  5. public CurrentProperty rule(HttpServletRequest request) {
  6. request.getServletPath(); // /hello
  7. request.getMethod(); // GET
  8. request.getRemoteHost(); // 127.0.0.1
  9. request.getSession(); // session
  10. return new CurrentProperty("Default",3,0,true,true);
  11. }
  12. }

CurrentProperty 构造方法参数说明:

参数 说明
id 标识名。若为IP地址则为IP地址限流,若为用户名则为用户限流,若为访问的URL则为接口限流。
qps 每秒并发量。支持小数、分数,计算规则:次数/时间(秒)。为0禁止访问。
initialDelay 首次放入令牌(即允许访问)延迟时间,可作为系统启动保护时间,单位/毫秒。
failFast 是否需开启快速失败。false即切换为阻塞。
overflow 是否严格控制请求速率和次数,true即切换为漏桶算法。

例如:对接口进行限流,只需要 request.getServletPath() 作为参数 id 的值即可。

8.关于作者

博客:http://www.yueshutong.cn

邮箱:yster@foxmail.com

Github:https://github.com/yueshutong/spring-boot-starter-current-limiting

Gitee:https://gitee.com/zyzpp/spring-boot-starter-current-limiting

交流QQ群:781927207

基于令牌桶算法实现的SpringBoot分布式无锁限流插件的更多相关文章

  1. coding++:RateLimiter 限流算法之漏桶算法、令牌桶算法--简介

    RateLimiter是Guava的concurrent包下的一个用于限制访问频率的类 <dependency> <groupId>com.google.guava</g ...

  2. php 基于redis使用令牌桶算法 计数器 漏桶算法 实现流量控制

    通常在高并发和大流量的情况下,一般限流是必须的.为了保证服务器正常的压力.那我们就聊一下几种限流的算法. 计数器计数器是一种最常用的一种方法,在一段时间间隔内,处理请求的数量固定的,超的就不做处理. ...

  3. RateLimiter令牌桶算法

    限流,是服务或者应用对自身保护的一种手段,通过限制或者拒绝调用方的流量,来保证自身的负载. 常用的限流算法有两种:漏桶算法和令牌桶算法 漏桶算法 思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度 ...

  4. 使用Redis实现令牌桶算法

    在限流算法中有一种令牌桶算法,该算法可以应对短暂的突发流量,这对于现实环境中流量不怎么均匀的情况特别有用,不会频繁的触发限流,对调用方比较友好. 例如,当前限制10qps,大多数情况下不会超过此数量, ...

  5. 限流10万QPS、跨域、过滤器、令牌桶算法-网关Gateway内容都在这儿

    一.微服务网关Spring Cloud Gateway 1.1 导引 文中内容包含:微服务网关限流10万QPS.跨域.过滤器.令牌桶算法. 在构建微服务系统中,必不可少的技术就是网关了,从早期的Zuu ...

  6. 15行python代码,帮你理解令牌桶算法

    本文转载自: http://www.tuicool.com/articles/aEBNRnU   在网络中传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送,令牌桶算法 ...

  7. flask结合令牌桶算法实现上传和下载速度限制

    限流.限速: 1.针对flask的单个路由进行限流,主要场景是上传文件和下载文件的场景 2.针对整个应用进行限流,方法:利用nginx网关做限流 本文针对第一中情况,利用令牌桶算法实现: 这个方法:h ...

  8. 令牌桶算法实现API限流

    令牌桶算法( Token Bucket )和 Leaky Bucket 效果一样但方向相反的算法,更加容易理解.随着时间流逝,系统会按恒定 1/QPS 时间间隔(如果 QPS=100 ,则间隔是 10 ...

  9. coding++:Semaphore—RateLimiter-漏桶算法-令牌桶算法

    java中对于生产者消费者模型,或者小米手机营销 1分钟卖多少台手机等都存在限流的思想在里面. 关于限流 目前存在两大类,从线程个数(jdk1.5 Semaphore)和RateLimiter速率(g ...

随机推荐

  1. 【安富莱TCPnet网络教程】HTTP通信实例

    第41章      HTTP超文本传输协议基础知识 本章节为大家讲解HTTP(HyperText Transfer Protocol,超文本传输协议),从本章节开始,正式进入嵌入式Web的设计和学习. ...

  2. .Net之Nopi Excel数据导出和批量导入功能

    一.介绍NPOI和编写demo的原因 1.Npoi是什么: 它是一个专门用于读写Microsoft Office二进制和OOXML文件格式的.NET库,我们使用它能够轻松的实现对应数据的导入,导出功能 ...

  3. 利用SQL Profiler 追踪数据库操作

    SQL Server 事件探查器 是一个界面,用于创建和管理跟踪并分析和重播跟踪结果. 这些事件保存在一个跟踪文件中,稍后试图诊断问题时,可以对该文件进行分析或用它来重播一系列特定的步骤. SQL S ...

  4. java游戏开发杂谈 - java是什么

    java是一门编程语言, 它有三个开发平台:j2ee.j2se. j2me.(其实android也算一个了)      j2ee, 也就是web开发,比如网站.各类管理系统,主要是围绕数据库.网页等进 ...

  5. Node.js 命令行工具的编写

    日常开发中,编写 Node.js 命令行工具来完成一些小任务是很常见的操作.其编写也不难,和日常编写 Node.js 代码并无二致. package.json 中的 bin 字段 一个 npm 模块, ...

  6. SpringSecurity设置角色和权限的注意点

    概念 在UserDetailsService的loadUserByUsername方法里去构建当前登陆的用户时,你可以选择两种授权方法,即角色授权和权限授权,对应使用的代码是hasRole和hasAu ...

  7. unity中ScriptableObject在assetbundle中的加载

    转载请标明出处:http://www.cnblogs.com/zblade/ 以前都是写一些个人的调研博客,从今天开始,也写一些个人在开发中遇到的一些可以分享的趟坑博客,为后续的开发人员提供一些绵薄之 ...

  8. Python编程从入门到实践笔记——异常和存储数据

    Python编程从入门到实践笔记——异常和存储数据 #coding=gbk #Python编程从入门到实践笔记——异常和存储数据 #10.3异常 #Python使用被称为异常的特殊对象来管理程序执行期 ...

  9. 编程心法 之 Scrum - Agile 敏捷开发

    Scrum是一种敏捷开发的方法 先定一个能达到的小目标 Scrum 团队 包括产品负责人.开发团队和Scrum Master Product Owner 产品负责人:管理代办事项和优先级的唯一负责人. ...

  10. HTML文档命名规则

    HTML文档是展示Web前段开发工程师成果的最好表示方式,为了便于文档规范化管理,在编写HTML文档时,必须遵循HTML文件命名规则. HTML文档命名规则如下: (1)文档的扩展名为htm或者htm ...