简单的限流RateLimiter

常用的限流算法:漏桶算法和令牌桶算法

漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。
令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。

RateLimiter是谷歌guava的包,引入pom依赖:

<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>27.0.1-jre</version>
</dependency>

RateLimiter是一个抽象类,但是提供了几个静态方法:

在这里插入图片描述
写在controller里面测试:

 /**
     * 创建一个稳定输出令牌的RateLimiter,保证了平均每秒不超过permitsPerSecond个请求
     * 当请求到来的速度超过了permitsPerSecond,保证每秒只处理permitsPerSecond个请求
     * 当这个RateLimiter使用不足(即请求到来速度小于permitsPerSecond),会囤积最多permitsPerSecond个请求
     */
//    private RateLimiter r = RateLimiter.create(1);

    /**
     * 创建一个稳定输出令牌的RateLimiter,保证了平均每秒不超过permitsPerSecond个请求
     * 还包含一个热身期(warmup period),热身期内,RateLimiter会平滑的将其释放令牌的速率加大,直到起达到最大速率
     * 同样,如果RateLimiter在热身期没有足够的请求(unused),则起速率会逐渐降低到冷却状态
     *
     * 设计这个的意图是为了满足那种资源提供方需要热身时间,而不是每次访问都能提供稳定速率的服务的情况(比如带缓存服务,需要定期刷新缓存的)
     * 参数warmupPeriod和unit决定了其从冷却状态到达最大速率的时间
     */
    private RateLimiter r = RateLimiter.create(1, 2, TimeUnit.SECONDS);

    @GetMapping("/rateLimiter")
    public String rateLimiter() {
        //尝试获取permits个令牌,带超时时间
        boolean b = r.tryAcquire(3,TimeUnit.SECONDS);
        //尝试获取permits个令牌,不带超时时间,直接返回的
//        boolean b = r.tryAcquire();
        if (!b) {
            return "限流了..";
        }
        return "欢迎光临";
    }

当刷新很快:
·在这里插入图片描述
在这里插入图片描述

posted @ 2019-04-07 16:07  你就像甜甜的益达  阅读(88)  评论(0编辑  收藏  举报