在令牌桶算法中有一个程序以某种恒定的速度生成令牌,并存入令牌桶中。每个请求必须先获取令牌才能执行,请求如果没有获取到令牌,可以选择等待,也可以放弃执行,如下图所示:
我们可以使用 Google 开源的 guava 包,很方便的实现令牌桶算法,首先在 pom.xml 添加 guava 引用,配置如下:
com.google.guava guava 28.2-jre
具体实现代码如下:
package com.example.demo; import com.google.common.util.concurrent.RateLimiter; import java.time.Instant; /** * 6种限流方法之服务端令牌算法 * * @author www.jiagou1216.com */public class RateLimiterDemo { public static void main(String[] args) { // 每秒产生 10 个令牌(每 100 ms 产生一个令牌) RateLimiter rt = RateLimiter.create(10); for (int i = 0; i < 11; i++) { new Thread(() -> { // 获取 1 个令牌 rt.acquire(); System.out.println("正常执行方法,ts:" + Instant.now()); }).start(); } }}
以上程序的执行结果为:
可以看到,令牌确实是每 100ms 产生一个,而 acquire() 方法为阻塞等待获取令牌,它可以接收一个 int 类型的参数,用于指定获取令牌的个数。替代方法还有 tryAcquire(),此方法在没有可用令牌时就会返回 false 这样就不会阻塞等待了。tryAcquire() 方法也可以设置超时时间,未超过最大等待时间会阻塞等待获取令牌,如果超过了最大等待时间仍然没有可用的令牌就会返回 false。
注意:
使用 google guava 实现的令牌算法属于程序级别的单机版限流方案,而上面使用 Redis-Cell 的是分布式的限流方案。
架构师小跟班,技术类综合网站,是本站长出于个人爱好,搭建的纯公益性质的博客网站,旨在为各位站长,程序员、学生提供免费的开发软件,视频教程,系统源码,网站模板等。
本站做过多次优化,解决了网站打开慢,谷歌浏览器报不安全提示等问题。
本站每周会有多次更新,内容完全免费,尤其是系统源码、毕业设计、视频教程等,没有任何套路,请大胆收藏和推荐。
但请粉丝们注意:
本站部分内容是站长从网络搜集所得,没有著作权,请勿用于商业用途,请下载后24小时内删除。谢谢合作!
领取专属 10元无门槛券
私享最新 技术干货