【如何】guava的RateLimiter使用

简介: 【如何】guava的RateLimiter使用

为什么要限流


在调用一些第三方的接口时,他们会有一些调用频率的限制,比如每秒不能超过多少次,这种时候,就需要用到限流的工具。


定义


还是给一个定义出来:


在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流


  • 缓存 缓存的目的是提升系统访问速度和增大系统处理容量


  • 降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再打开


  • 限流 限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理


如何限流


傻瓜方案


因为我们需要限流的地方是对第三方调用的时候,我们是在循环里调用的第三方,所以,简单粗暴的Thread.sleep(500) 其实也可以用。


正式方案


Guava的RateLimiter算是比较方便的限流工具。


Guava RateLimiter基于令牌桶算法,我们只需要告诉RateLimiter系统限制的QPS是多少,那么RateLimiter将以这个速度往桶里面放入令牌,然后请求的时候,通过acquire()方法向RateLimiter获取许可(令牌)。


来个例子


public static void main(String[] args) {
        // qps设置为2,代表一秒钟只允许处理2个并发请求
        RateLimiter rateLimiter = RateLimiter.create(2);
        StopWatch sw=new StopWatch();
        sw.start();
        int nTasks = 10;
        for (int i = 0; i < nTasks; i++) {
            rateLimiter.acquire(1);
            sw.split();
            System.out.println("job id is "+i+"sw: "+sw.getSplitTime());
            //sw.shortSummary();
        }
        sw.stop();
        System.out.println("finish,total time is "+sw.getTime());
    }


输出是这样的:


job id is 0sw: 0
job id is 1sw: 497
job id is 2sw: 998
job id is 3sw: 1499
job id is 4sw: 2002
job id is 5sw: 2498
job id is 6sw: 2997
job id is 7sw: 3497
job id is 8sw: 3998
job id is 9sw: 4502
finish,total time is 4502


注意


有一点需要注意,RateLimiter的这个令牌是会累积的,也就是说,就算令牌不使用,也会积攒下来,当需要使用的时候,一股脑的给出去。


RateLimiter rateLimiter = RateLimiter.create(2);
//追一下代码
    public static RateLimiter create(double permitsPerSecond) {
        return create(permitsPerSecond, RateLimiter.SleepingStopwatch.createFromSystemTimer());
    }
    @VisibleForTesting
    static RateLimiter create(double permitsPerSecond, RateLimiter.SleepingStopwatch stopwatch) {
        RateLimiter rateLimiter = new SmoothBursty(stopwatch, 1.0D);
        rateLimiter.setRate(permitsPerSecond);
        return rateLimiter;
    }


可以看到,默认情况下,最多累积1s钟的令牌。


测试一下,代码:


    @SneakyThrows
    public static void main(String[] args) {
        // qps设置为2,代表一秒钟只允许处理2个并发请求
        RateLimiter rateLimiter = RateLimiter.create(2);
        StopWatch sw=new StopWatch();
        sw.start();
        int nTasks = 10;
        Thread.sleep(3000);
        for (int i = 0; i < nTasks; i++) {
            rateLimiter.acquire(1);
            sw.split();
            System.out.println("job id is "+i+"sw: "+sw.getSplitTime());
            //sw.shortSummary();
        }
        sw.stop();
        System.out.println("finish,total time is "+sw.getTime());
    }


结果:


job id is 0sw: 3009
job id is 1sw: 3010
job id is 2sw: 3010
job id is 3sw: 3509
job id is 4sw: 4009
job id is 5sw: 4510
job id is 6sw: 5008
job id is 7sw: 5506
job id is 8sw: 6007
job id is 9sw: 6508
finish,total time is 6508


如果你想多累积几秒,那么创建的时候应该是:


        RateLimiter rateLimiter = RateLimiter.create(2);
        rateLimiter.setRate(3D);


高并发之API接口限流

目录
相关文章
|
存储 缓存 算法
Google Guava之RateLimiter
在日常开发中,限流是高并发系统的三把守护利器之一,它的另外两个好兄弟缓存、降级下次再说。而限流在绝大多数场景中用来限制并发和请求量,像秒杀之类的高流量业务的场景,都能见到它的身影,所以它就是保护系统和下游的业务系统不被流量冲垮的利器。
305 6
Google Guava之RateLimiter
|
6月前
|
Java Maven
Guava RateLimiter单机实战指南
Guava RateLimiter单机实战指南
49 0
|
6月前
|
存储 缓存 NoSQL
Guava 缓存详解及使用
Guava Cache 是`Google Fuava`中的一个内存缓存模块,用于将数据缓存到JVM内存中。 本文主要介绍下Guava缓存的配置详解及相关使用 缓存分为本地缓存与分布式缓存。本地缓存为了保证线程安全问题,一般使用`ConcurrentMap`的方式保存在内存之中,而常见的分布式缓存则有`Redis`,`MongoDB`等。
|
6月前
|
NoSQL Java Redis
SpringBoot 中使用布隆过滤器 Guava、Redission实现2
SpringBoot 中使用布隆过滤器 Guava、Redission实现
126 0
|
6月前
|
NoSQL Java Redis
SpringBoot 中使用布隆过滤器 Guava、Redission实现 1
SpringBoot 中使用布隆过滤器 Guava、Redission实现
261 0
|
存储 算法 NoSQL
RateLimiter源码分析
RateLimiter源码分析
155 0
RateLimiter源码分析
|
Java
SpringBoot整合RateLimiter实现限流
写作缘由 在和某学长炫耀在自己会用Redis+Lua实现滑动窗口限流时,他说现在都用RateLimiter,所以就我就想搞个Demo,但是度娘了一下,感觉我搜索到的博客有几个个人认为不太完善的地方,比如只贴了部分代码,没贴依赖。尤其是你用AOP实现的时候,其实依赖哪个还有有讲究的;还有一个问题就是大多都是基于AOP实现,拦截器实现也是一个不错的方式,所以此处用拦截器HandlerInterceptorAdapter实现。
325 0
|
缓存 算法 Java
使用Guava实现限流器
使用Guava实现限流器
646 0
使用Guava实现限流器
|
算法 前端开发 Java
实战限流(guava的RateLimiter)
guava的RateLimiter使用的是令牌桶算法,也就是以固定的频率向桶中放入令牌,本文实战一下RateLimiter的用法
1249 0
实战限流(guava的RateLimiter)
|
存储 算法 Java
超详细的Guava RateLimiter限流原理解析
限流是保护高并发系统的三把利器之一,另外两个是缓存和降级。限流在很多场景中用来限制并发和请求量,比如说秒杀抢购,保护自身系统和下游系统不被巨型流量冲垮等。