rate-limit 一款 java 开源渐进式分布式限流框架使用介绍
项目简介
rate-limit 是一个为 java 设计的渐进式限流工具。
目的是为了深入学习和使用限流,后续将会持续迭代。
特性
渐进式实现
支持独立于 spring 使用
支持整合 spring
支持整合 spring-boot
内置多种限流策略

快速开始
需求
jdk 1.7
maven 3.x+
maven 导入
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>rate-limit-core</artifactId>
<version>1.1.0</version>
</dependency>
入门例子
方法定义
@RateLimit 限流注解放在方法上,指定对应的限制频率。
也可以定义在类上,默认下面的所有方法生效。方法上的优先级高于类。
| 属性 | 说明 | 默认值 |
|---|---|---|
| value | 方法访问一次消耗的令牌数 | 1 |
| timeUnit | 时间单位 | TimeUnit.SECONDS |
| interval | 时间间隔 | 60 |
| count | 可调用次数 | 1000 |
| enable | 是否启用 | true |
默认为 60S 内,可以调用 1000 次。
public class UserService {
@RateLimit(interval = 2, count = 5)
public void limitCount() {
log.info("{}", Thread.currentThread().getName());
}
}
这个例子中我们 2S 内最多调用 5 次。
代码测试
RateLimitProxy.getProxy(xxx) 通过字节码获取方法对应的方法代理。
@Test(expected = RateLimitRuntimeException.class)
public void limitCountErrorTest() {
UserService userService = RateLimitProxy.getProxy(new UserService());
for(int i = 0; i < 3; i++) {
userService.limitCount();
}
}
当调用超出限制时,默认抛出 RateLimitRuntimeException 异常。
这里默认使用的是令牌桶算法,所以会出现异常。
重复注解 @RateLimits
有时候我们希望同时做多个的限制:
(1)一分钟不超过 10 次
(2)一小时不超过 30 次
为了支持多个配置,我们引入了新的注解 @RateLimits,可以指定一个 @RateLimit 数组。
方法上同时使用 @RateLimits + @RateLimit 是可以同时生效的,不过为了简单,一般不建议混合使用。
@RateLimits({@RateLimit(interval = 2, count = 5)})
public void limitCount() {
//...
}
指定引导类
RateLimitProxy.getProxy(new UserService());
等价于
RateLimitProxy.getProxy(new UserService(), RateLimitBs.newInstance());
下面我们来一起看一下 RateLimitBs 引导类。
引导类
RateLimitBs 作为引导类,便于用户自定义配置。
| 方法 | 说明 | 默认值 |
|---|---|---|
| rateLimit | 限流策略 | RateLimits.tokenBucket() 令牌桶算法 |
| timer | 时间策略 | Timers.system() 系统时间 |
| cacheService | 缓存策略 | CommonCacheServiceMap 基于本地 map 的缓存策略 |
| cacheKeyNamespace | 缓存KEY命名空间 | RATE-LIMIT 避免不同的应用,命名冲突。 |
| configService | 限制配置策略 | RateLimitConfigService 默认基于方法上的注解 |
| tokenService | 身份标识策略 | RateLimitTokenService 默认基于 IP |
| methodService | 方法标识策略 | RateLimitMethodService 默认基于方法名+参数类型 |
| rejectListener | 拒绝策略 | RateLimitRejectListenerException 限流时抛出异常 |
其中 rateLimit 内置 RateLimits 工具中的策略如下:
| 方法 | 说明 |
|---|---|
| fixedWindow() | 固定窗口 |
| slideWindow(int windowNum) | 滑动窗口,可指定窗口大小 |
| slideWindow() | 滑动窗口,默认为 10 |
| slideWindowQueue() | 滑动窗口,基于队列的实现 |
| leakyBucket() | 漏桶算法 |
| tokenBucket() | 令牌桶算法 |
配置建议
分布式系统,cacheService 建议使用基于 redis 的集中式缓存策略。
configService 如果想更加灵活,可以基于数据库的配置查询
RateLimitBs 引导类
RateLimitBs 默认配置如下:
RateLimitBs.newInstance()
.timer(Timers.system())
.methodService(new RateLimitMethodService())
.tokenService(new RateLimitTokenService())
.rejectListener(new RateLimitRejectListenerException())
.configService(new RateLimitConfigService())
.cacheService(new CommonCacheServiceMap())
.rateLimit(RateLimits.tokenBucket())
.cacheKeyNamespace(RateLimitConst.DEFAULT_CACHE_KEY_NAMESPACE);
spring 整合
maven 引入
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>rate-limit-spring</artifactId>
<version>1.1.0</version>
</dependency>
类定义
方法
和上面使用类似,直接在方法上声明 @RateLimit 注解即可。
@Service
public class UserService {
private static final Log log = LogFactory.getLog(UserService.class);
@RateLimit(interval = 2, count = 5)
public void limitCount() {
log.info("{}", Thread.currentThread().getName());
}
}
配置
通过 @EnableRateLimit 声明启用限流。
@Configuration
@ComponentScan("com.github.houbb.rate.limit.test.core")
@EnableRateLimit
public class SpringConfig {
}
@EnableRateLimit 的属性配置和 RateLimitBs 属性是以一一对应的。
| 方法 | 说明 | 默认值 |
|---|---|---|
| rateLimit | 限流策略 | 令牌桶算法 |
| timer | 时间策略 | 系统时间 |
| cacheService | 缓存策略 | 基于本地 map 的缓存策略 |
| cacheKeyNamespace | 缓存KEY命名空间 | RATE-LIMIT 避免不同的应用,命名冲突。 |
| configService | 限制配置策略 | 默认基于方法上的注解 |
| tokenService | 身份标识策略 | 默认基于 IP |
| methodService | 方法标识策略 | 默认基于方法名+参数类型 |
| rejectListener | 拒绝策略 | 限流时抛出异常 |
这里的属性值,都是对应的 spring bean 名称,支持用户自定义。
spring-boot 整合
maven 引入
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>rate-limit-springboot-starter</artifactId>
<version>1.1.0</version>
</dependency>
使用
其他和 spring 保持一致。
缓存相关工具
redis-config: 兼容各种常见的 redis 配置模式
rate-limit 一款 java 开源渐进式分布式限流框架使用介绍的更多相关文章
- 阿里巴巴的26款Java开源项目
阿里巴巴的26款Java开源项目 开源展示了人类共同协作,成果分享的魅力.没有任何一家网络公司可以不使用开源技术,仅靠自身技术发展起来.“取之于开源,用之于开源,才能促进开源的良性发展”,阿里巴巴各个 ...
- 分布式限流组件-基于Redis的注解支持的Ratelimiter
原文:https://juejin.im/entry/5bd491c85188255ac2629bef?utm_source=coffeephp.com 在分布式领域,我们难免会遇到并发量突增,对后端 ...
- Redis实现的分布式锁和分布式限流
随着现在分布式越来越普遍,分布式锁也十分常用,我的上一篇文章解释了使用zookeeper实现分布式锁(传送门),本次咱们说一下如何用Redis实现分布式锁和分布限流. Redis有个事务锁,就是如下的 ...
- 限流(三)Redis + lua分布式限流
一.简介 1)分布式限流 如果是单实例项目,我们使用Guava这样的轻便又高性能的堆缓存来处理限流.但是当项目发展为多实例了以后呢?这时候我们就需要采用分布式限流的方式,分布式限流可以以redis + ...
- Springboot分布式限流实践
高并发访问时,缓存.限流.降级往往是系统的利剑,在互联网蓬勃发展的时期,经常会面临因用户暴涨导致的请求不可用的情况,甚至引发连锁反映导致整个系统崩溃.这个时候常见的解决方案之一就是限流了,当请求达到一 ...
- 【分布式架构】--- 基于Redis组件的特性,实现一个分布式限流
分布式---基于Redis进行接口IP限流 场景 为了防止我们的接口被人恶意访问,比如有人通过JMeter工具频繁访问我们的接口,导致接口响应变慢甚至崩溃,所以我们需要对一些特定的接口进行IP限流,即 ...
- Sentinel整合Dubbo限流实战(分布式限流)
之前我们了解了 Sentinel 集成 SpringBoot实现限流,也探讨了Sentinel的限流基本原理,那么接下去我们来学习一下Sentinel整合Dubbo及 Nacos 实现动态数据源的限流 ...
- 基于kubernetes的分布式限流
做为一个数据上报系统,随着接入量越来越大,由于 API 接口无法控制调用方的行为,因此当遇到瞬时请求量激增时,会导致接口占用过多服务器资源,使得其他请求响应速度降低或是超时,更有甚者可能导致服务器宕机 ...
- 国内最火的10款Java开源项目,都是国人开发,CMS居多
原文链接:https://www.cnblogs.com/jimcsharp/p/8266954.html 国内的开源环境已经相当好,但是国内开发注重是应用,创新有但不多,从榜单可以看出,专门搞技术的 ...
- 推荐十款java开源中文分词组件
1:Elasticsearch的开源中文分词器 IK Analysis(Star:2471) IK中文分词器在Elasticsearch上的使用.原生IK中文分词是从文件系统中读取词典,es-ik本身 ...
随机推荐
- (四)JPA - JQPL 实现增删改查
(一)JPA的快速入门 建议在需要使用时,看看之前的文章,先把环境搭起来. 5.JPQL JPQL和SQL 1.JPQL和SQL很像,查询关键字都是一样的 2.唯一的区别是:JPQL是面向对象的 JP ...
- MES系统和ERP系统的区别是什么?
首先得明白一点:MES(Manufacturing Execution System,即制造执行系统)系统跟ERP(Enterprise Resource Planning,企业资源计划)系统是两个完 ...
- 洛谷P3870 [TJOI2009] 开关 (线段树)
简单的省选题...... 打异或标记即可. 1 #include<bits/stdc++.h> 2 const int N=2e5+10; 3 using namespace std; 4 ...
- 达梦dba_segments指定表名查询到的大小都包含哪些数据
一.结论 dba_segments指定表名查询到的段大小包含索引.约束.表字段数据(包含LOB字段)(1)表(不包含LOB字段)创建默认分配2个簇,1个簇用于存放表结构及字段数据,1个簇用于存放clu ...
- RAID5 IO处理之写请求代码详解
我们知道RAID5一个条带上的数据是由N个数据块和1个校验块组成,其校验块由N个数据块通过异或运算得出,这样才能在任意一个成员磁盘失效时通过其他N个成员磁盘恢复出用户写入的数据.这也就要求RAID5条 ...
- [Thread] Synchronized
1.Monitor对象 Monitor对象被称为管程或者监视器锁. 在Java中,每一个对象实例都会关联一个Monitor对象. 这个Monitor对象既可以与对象一起创建销毁,也可以在线程试图获取对 ...
- 基于tauri+vue3.x多开窗口|Tauri创建多窗体实践
最近一种在捣鼓 Tauri 集成 Vue3 技术开发桌面端应用实践,tauri 实现创建多窗口,窗口之间通讯功能. 开始正文之前,先来了解下 tauri 结合 vue3.js 快速创建项目. taur ...
- jsp和java的结合使用显示学生信息
package com.zyz; public class Student { private String ID; // 学号 private String name; // 姓名 private ...
- elementUi使用dialog的进行信息的添加、删除表格数据时进行信息提示。删除或者添加成功的信息提示(SpringBoot+Vue+MybatisPlus)
文章目录 1.添加新用户,通过dialog的弹窗形式 1.1 添加的按钮 1.2 调用方法设置窗口可见 1.3 窗口代码 1.4 提交注册信息方法 1.5 使用mybatisPlus方法进行添加信息到 ...
- 怎样在vue中隐藏el-form-item中的值、设置输入框的值是只读
1.如何在前端vue中隐藏某一个元素(el-form-item怎样隐藏) 给每项表单项添加一个自己的id名,并用v-model绑定相对应的数据,利用v-if根据上一个表单项的数据值来进行显示或隐藏 & ...