自定义限速功能实践——Caffeine
之前使用了 JDK 自带的 Map
实现了自定义限速的简单需求。在当时的实现当中,有一个被隐藏的小设计,就是如果是用使用异步线程,用来根据配置给请求次数数据重置。如此这样,校验方法会非常简单方便。
对于普通 Java
项目来说,如果使用异步线程处理,除了 deamon
进程以外,其他实现的确有点麻烦。即使 deamon
线程也很难做到完全的实用性,所以才使用了上篇文章的实现方案。
之前提到过一个非常有趣的高性能本地缓存 Caffeine
刚好能解决这个问题,可以通过缓存过期或者定时刷新功能来实现定时刷新的需求。这里我选择了定时刷新功能,这种选择会限制限流配置的种类,无法进行 2/3s
, 10/2s
配置,我最终选择 TPS
进行配置,全部使用 1s
为限制周期。
代码
主要思路如下:
数据结构选择:使用了两种数据结构来实现限流功能:使用了一个 Map 来存储每个请求的限流配置,以请求的标识符作为键,以该请求的每秒事务数(TPS)作为值;使用了 Caffeine 缓存来存储每个请求的计数器,其中键为请求的标识符,值为一个原子整数,用于记录请求的处理数量。
限流判断逻辑:具体逻辑如下:首先从缓存中获取对应请求的计数器;判断当前计数器的值是否大于等于该请求的配置的每秒事务数(TPS);如果超过了配置的值,则表示需要限流,返回 true。否则,递增计数器并返回 false,表示不需要限流。
动态配置:动态添加请求的限流配置,将请求的标识符和对应的每秒事务数(TPS)添加到配置中,实现了动态配置的功能。
使用 Caffeine 缓存:使用了 Caffeine 缓存来存储请求的计数器,可以配置缓存的过期时间(1 秒),当缓存过期时会自动刷新。这样可以确保计数器在一定时间内有效,避免长时间未使用的请求占用内存。
代码如下:
测试
测试脚本如下,与前一篇文章大同小异:
控制台输出:
可以看出,按照默认配置 1 TPS 的配置实现。
版权声明: 本文为 InfoQ 作者【FunTester】的原创文章。
原文链接:【http://xie.infoq.cn/article/46d04787dbdd2560567dbfb07】。文章转载请联系作者。
评论