Springboot项目中通过谷歌的guava实现令牌桶算法,来进行请求限流

  • Post author:
  • Post category:其他



令牌桶算法

是一种对请求限流的有效算法,核心思想是,一定时间内产生

固定数量的令牌

,拿到该令牌的请求可以通过,进行业务处理,没有拿到令牌的请求需要等待,直到新的令牌产生并领到该令牌,才可以通过,否则一直被阻塞或一定时间后拒绝。

在这里插入图片描述


令牌桶算法

相比

漏斗算法

,更加灵活、可控制。在java中,Google的

Guava

中有对令牌桶算法的实现,我们可以直接拿过来使用:



1. 依赖

        <!-- google开源工具类,包含令牌桶算法 -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>28.2-jre</version>
        </dependency>



2. 使用

	//创建令牌桶实例,30指一开始最大有30个令牌,并且每次生成30个
    private RateLimiter rateLimiter = RateLimiter.create(30);

	@GetMapping("/sale")
    public AjaxResponse sale(Integer id){
        AjaxResponse ajax = AjaxResponse.newSuccess();
        try {
            //1.没有获取到token请求一直直到获取到token令牌
            //logger.info("等待时间 : " + rateLimiter.acquire());   //会一直等待
            //2.设置一个等待时间,如果在等待的时间内获得到了token令牌,则处理业务,如果在等待时间内没有获取到token则抛弃
            //最多等待3秒钟,3秒钟后还拿不到令牌就被抛弃
            if(!rateLimiter.tryAcquire(3, TimeUnit.SECONDS)){
                ajax.setData("失败 !当前请求被限流,直接被抛弃");
                return ajax;
            }
            try {

                //一些自己的业务
                //............
                ajax.setData("SUCCESS!");
                return ajax;

            }catch (Exception e){
                e.printStackTrace();
                return AjaxResponse.newInstance(500,e.getMessage());
            }

        }catch (Exception e){
            e.printStackTrace();
            return AjaxResponse.newInstance(500,e.getMessage());
        }
    }

我们可以看到核心的两个调用,一个是

rateLimiter.acquire()

,类似于

悲观锁

,没有拿到令牌的请求会一直被阻塞,直至拿到了令牌、另一个是

rateLimiter.tryAcquire(3, TimeUnit.SECONDS)

,指没有拿到令牌的请求最多等待3秒钟,3秒之后拿到令牌返回true,没有返回false,可以根据的业务场景进行开发。

相对于springcloud,有专门的

hytrix



sentinel

来进行限流和频率限制更加厉害。如果只是单纯普通的springboot项目,使用guava中的令牌桶算法来对请求进行限流是一种不错的方式。



版权声明:本文为weixin_42822484原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。