项目简介

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() 令牌桶算法

配置建议

  1. 分布式系统,cacheService 建议使用基于 redis 的集中式缓存策略。

  2. 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 保持一致。

缓存相关工具

cache: 手写渐进式 redis

common-cache: 通用缓存标准定义

redis-config: 兼容各种常见的 redis 配置模式

lock: 开箱即用的分布式锁

resubmit: 防重复提交

rate-limit: 限流

rate-limit 一款 java 开源渐进式分布式限流框架使用介绍的更多相关文章

  1. 阿里巴巴的26款Java开源项目

    阿里巴巴的26款Java开源项目 开源展示了人类共同协作,成果分享的魅力.没有任何一家网络公司可以不使用开源技术,仅靠自身技术发展起来.“取之于开源,用之于开源,才能促进开源的良性发展”,阿里巴巴各个 ...

  2. 分布式限流组件-基于Redis的注解支持的Ratelimiter

    原文:https://juejin.im/entry/5bd491c85188255ac2629bef?utm_source=coffeephp.com 在分布式领域,我们难免会遇到并发量突增,对后端 ...

  3. Redis实现的分布式锁和分布式限流

    随着现在分布式越来越普遍,分布式锁也十分常用,我的上一篇文章解释了使用zookeeper实现分布式锁(传送门),本次咱们说一下如何用Redis实现分布式锁和分布限流. Redis有个事务锁,就是如下的 ...

  4. 限流(三)Redis + lua分布式限流

    一.简介 1)分布式限流 如果是单实例项目,我们使用Guava这样的轻便又高性能的堆缓存来处理限流.但是当项目发展为多实例了以后呢?这时候我们就需要采用分布式限流的方式,分布式限流可以以redis + ...

  5. Springboot分布式限流实践

    高并发访问时,缓存.限流.降级往往是系统的利剑,在互联网蓬勃发展的时期,经常会面临因用户暴涨导致的请求不可用的情况,甚至引发连锁反映导致整个系统崩溃.这个时候常见的解决方案之一就是限流了,当请求达到一 ...

  6. 【分布式架构】--- 基于Redis组件的特性,实现一个分布式限流

    分布式---基于Redis进行接口IP限流 场景 为了防止我们的接口被人恶意访问,比如有人通过JMeter工具频繁访问我们的接口,导致接口响应变慢甚至崩溃,所以我们需要对一些特定的接口进行IP限流,即 ...

  7. Sentinel整合Dubbo限流实战(分布式限流)

    之前我们了解了 Sentinel 集成 SpringBoot实现限流,也探讨了Sentinel的限流基本原理,那么接下去我们来学习一下Sentinel整合Dubbo及 Nacos 实现动态数据源的限流 ...

  8. 基于kubernetes的分布式限流

    做为一个数据上报系统,随着接入量越来越大,由于 API 接口无法控制调用方的行为,因此当遇到瞬时请求量激增时,会导致接口占用过多服务器资源,使得其他请求响应速度降低或是超时,更有甚者可能导致服务器宕机 ...

  9. 国内最火的10款Java开源项目,都是国人开发,CMS居多

    原文链接:https://www.cnblogs.com/jimcsharp/p/8266954.html 国内的开源环境已经相当好,但是国内开发注重是应用,创新有但不多,从榜单可以看出,专门搞技术的 ...

  10. 推荐十款java开源中文分词组件

    1:Elasticsearch的开源中文分词器 IK Analysis(Star:2471) IK中文分词器在Elasticsearch上的使用.原生IK中文分词是从文件系统中读取词典,es-ik本身 ...

随机推荐

  1. MySQL学习(3)---MySQL常用命令

    ps:此随笔基于mysql 5.7.*版本. 准备 net start mysql 启动MySQL服务 net stop mysql 关闭MySQL服务 mysql [-h<IP地址>] ...

  2. 数据火器库八卦系列之瑞士军刀随APP携带的SQLite

    来源:云数据库技术 数据库打工仔喃喃自语的八卦历史 1. 为导弹巡洋舰设计,用在手机上的数据库 2. Small and Simple, and Better 3. 如何看出是自己的娃:产品定位,特点 ...

  3. C语言下for循环的一点技巧总结

    for循环是普遍应用与各种计算机语言的一种循环方式. 一般情况下, for循环规则:for(条件一:条件二:条件三) 条件一为满足条件,也就是条件一为1时,进入这个for循环.条件二为循环条件,也就是 ...

  4. mysql工具的使用、增删改查

    mysql工具使用 目录 mysql工具使用 mysql的程序组成 mysql工具使用 服务器监听的两种socket地址 mysql数据库操作 DDL操作 数据库操作 表操作 用户操作 查看命令SHO ...

  5. JavaBean组件<jsp:forward>动作<jsp:param>动作登录页面输入用户名和密码,然后进入检查页面判断是否符合要求,符合要求跳转到成功界面,不符合要求返回登录界面,显示错误信息。

    JavaBean组件 JavaBean组件实际是一种java类.通过封装属性和方法成为具有某种功能或者处理某个业务的对象. 特点:1.实现代码的重复利用.2.容易编写和维护.3.jsp页面调用方便. ...

  6. 『现学现忘』Git分支 — 40、分支基本操作(一)

    目录 1.创建分支 (1)创建分支 (2)图示理解 2.查看分支列表 3.分支切换 4.查看所有分支的最后一个提交 5.删除分支 1.创建分支 (1)创建分支 Git 是怎么创建新分支的呢? 很简单, ...

  7. Linux系统文件与启动流程

    Linux系统文件与启动流程 /etc初始化系统重要文件 /etc/sysconfig/network-scripts/ifcfg-eth0:网卡配置文件 /etc/resolv.conf:Linux ...

  8. 打地鼠(susliks) 方法记录

    [SDOI2011]打地鼠 题目描述 2020.4.29 数据更新. 打地鼠是这样的一个游戏:地面上有一些地鼠洞,地鼠们会不时从洞里探出头来很短时间后又缩回洞中.玩家的目标是在地鼠伸出头时,用锤子砸其 ...

  9. VM虚拟机搭建Linux CentOS7(手把手教程)

    VM虚拟机搭建Linux CentOS7(手把手教程) 目录 VM虚拟机搭建Linux CentOS7(手把手教程) 一.VM虚拟机和Linux镜像文件下载 1. 登录VM虚拟机官方地址: 2. 安装 ...

  10. C# 多线程访问之 SemaphoreSlim(信号量)【C# 进阶】

    SemaphoreSlim 是对可同时访问某一共享资源或资源池的线程数加以限制的 Semaphore 的轻量替代,也可在等待时间预计很短的情况下用于在单个进程内等待. 由于 SemaphoreSlim ...