ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

RateLimiter限流器

2020-06-11 17:56:46  阅读:268  来源: 互联网

标签:令牌 RateLimiter System long 限流 out


  • RateLimiter是基于令牌桶算法实现的一个多线程限流器,它可以将请求均匀的进行处理,当然他并不是一个分布式限流器,只是对单机进行限流。它可以应用在定时拉取接口数。 通过aop、filter、Interceptor 等都可以达到限流效果。
原理特别简单、轻量。引入guava包即可。
package com.ratelimiter;

import com.google.common.util.concurrent.RateLimiter;

import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * RateLimiter是基于令牌桶算法实现的一个多线程限流器,它可以将请求均匀的进行处理,当然他并不是一个分布式限流器,只是对单机进行限流。它可以应用在定时拉取接口数据,
 *
 * @version 1.0
 * @date 2020-06-11 10:08
 **/
public class RateMain {

    public static void main(String[] args) throws InterruptedException {
        long l = MILLISECONDS.toMicros(1L);
        long l1 = MILLISECONDS.toMillis(1L);
        long l2 = SECONDS.toMicros(1L);
        System.out.println("RateMain.main = " + l + "====" + l1 + "====" + l2);
        System.out.println("RateMain.main jdk8 新特性无穷大 = " + ((1.0 / 0.0) > 9.99));
        RateLimiter rateLimiter = RateLimiter.create(1000);
        MILLISECONDS.sleep(1000L); // sleep 1s, 那么会导致初始化10个令牌
        int i = 0;
        do {
            long start = System.currentTimeMillis();
            boolean b = rateLimiter.tryAcquire();
//            double b = rateLimiter.acquire();  // 取的令牌,返回获取令牌的耗时。
            System.out.print(System.currentTimeMillis() - start);
            System.out.println("第" + (++i) + "条, 获取令牌:" + b);
            if (i > 50) {
                break;
            }
        } while (true);
    }
}

原理

首先先讲一下令牌桶的原理,每隔一段时间生产一个令牌放入桶里,请求在执行时需要拿到令牌才可以执行,如果拿不到令牌将等待令牌产生,一个生产者,多个消费者。

但是这样的令牌桶有一个问题,如果CPU负载过高,生产令牌的线程没有获取到时间片生产令牌,那么限制的流量将会比设定值更低。

可能是出于这个原因,guava并没有这样做,而是一个惰性生产令牌:

每次请求令牌时,通过当前时间和下次产生令牌时间的差值计算出现在有多少个令牌。
storedPermits: 已有令牌数量
nextFreeTicketMicros: 下次产生令牌的时间点
stableIntervalMicros: 产生一个令牌需要的时间,例如10qps,  = 1000/10 = 100ms会产生一个令牌

例如:获取令牌时,当前时间比下次产生令牌时间大,
会计算出令牌存储[(now-nextFreeTicketMicros)/stableIntervalMicros],如果令牌不够,则让线程sleep;
每次新生产令牌,下次产生令牌的时间点更新成当前时间时间(有等待,需要加上等待时间)。

断点进去就可以了。

标签:令牌,RateLimiter,System,long,限流,out
来源: https://www.cnblogs.com/bestzhang/p/13094766.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有