当前位置:   article > 正文

Java服务限流之Guava_guava maven

guava maven


一、为什么需要限流?

相信大家在工作中肯定都会遇到,随着业务的发展,需要不停的提升服务的性能,但是单台机器的性能终归是有限的!为防止服务器因为请求量过大而导致服务不可用的情况,都需要针对接口等维度进行限流控制,就引出了在服务中使用限流器。


二、Google开源工具包Guava

Google开源的工具包Guava具备很多强大的功能,限流器就是其中之一,本文主要介绍限流器相关实现原理和使用。
除此之外,Guava还在字符串、集合、网络、文件、并发等各种方面提供了更加强大和方便操作的工具类。


三、Guava限流算法介绍

1.算法介绍

Google开源的工具包Guava具备很多强大的功能,限流器就是其中之一。
常见的限流算法主要有固定窗口、滑动窗口、漏桶、令牌桶算法这几种(知道更多的可以评论补充下~)。
Guava的限流算法是基于令牌桶来实现的!下面为大家通俗介绍下令牌桶算法:

令牌桶算法核心就是一个维护一个固定容量令牌的容器(就是桶),按照固定速率往桶里添加令牌。
桶中最多存放N个令牌,当桶满时,新添加的令牌被丢弃;
当接收到请求时,去桶中获取一个令牌,获取到则继续执行,并删除对应的令牌;
未获取到令牌则丢弃请求(被限流)。

在这里插入图片描述
   

2.Guava限流工具类RateLimiter

guava实现限流的主要类是RateLimiter,下图是RateLimiter的主要方法。
在这里插入图片描述
主要的方法有:

  • create: 创建对象RateLimiter对象,参数主要为限制每秒通过限流器的请求数量,可传入TimeUnit设置时间单位。
  • acquire: 会阻塞等待限流,拿到令牌再执行,不常用。
  • tryAcquire: 非阻塞限流 ,不会等待,直接返回布尔值,业务依据布尔值进行处理,常用。

四、使用步骤

1.引入maven依赖

引入google.guava依赖

    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>30.0-android</version>
    </dependency>	
  • 1
  • 2
  • 3
  • 4
  • 5

2.简单使用

1.阻塞限流:acquire

    public static void blockLimit() {
        Long start = System.currentTimeMillis();
        RateLimiter limiter = RateLimiter.create(1.0); // 限制每秒通过的数量
        for (int i = 0; i < 20; i++) {
            limiter.acquire(); // 限流,超过的部分会被阻塞,等待令牌后继续执行
            Long end = System.currentTimeMillis();
            System.out.println("call execute.." + i);
            System.out.println("time: " + (end - start)/1000 + "s");
        }
    }	
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

运行该段代码后的结果如下,可以看到后续的请求都被阻塞,每一秒钟会执行一次。

call execute…0
time: 0s
call execute…1
time: 1s
call execute…2
time: 2s
call execute…3
time: 3s
call execute…4
time: 4s

2.非阻塞限流:tryAcquire

    public static void nonBlockLimit() {
        Long start = System.currentTimeMillis();
        RateLimiter limiter = RateLimiter.create(100.0); // 限制每秒通过的数量
        for (int i = 0; i < 20; i++) {
            boolean b = limiter.tryAcquire(); // 限流,返回布尔值,非阻塞
            if (b) {
                System.out.println("execute.." + i);
            } else {
                System.out.println("request too frequently" );
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

运行该段代码后的结果如下,可以看到只有第一次执行,后续都是请求过于频繁,因为请求都是在1s内完成的。一般来说都是使用tryAcquire方法。

execute…0
request too frequently
request too frequently
request too frequently
request too frequently
request too frequently


四、总结

综上,Guava在针对单机或者在集群中对单台机器进行qps、tps进行限制时表现的非常可靠和稳定,是个不错的选择。但是无法满足在分布式系统中进行分布式限流!后续会再进行分布式限流的介绍。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/828855?site
推荐阅读
相关标签
  

闽ICP备14008679号