关于Guava中令牌桶算法RateLimiter的理解

来源:互联网 发布:中国指数研究院 知乎 编辑:程序博客网 时间:2024/06/16 03:22

      我们系统现在架构是收到mq消息,先放到redis队列,然后再从redis队列取任务去消费,当上游刷数据的时候,redis队列任务就会非常多,这个时候我们在消费的时候既要考虑redis的稳定性,也要考虑调用下游资源所能提供资源能力。对于资源受限、处理能力不是很强的资源应当给予保护(在下游资源无法或者短时间内无法提升处理性能的情况下)。可以使用限流器或者类似保护机制,避免下游服务崩溃造成整体服务的不可用。这是我们用到了Guava的令牌桶算法RateLimiter

RateLimiter类似于JDK的信号量Semphore,他用来限制对资源并发访问的线程数

    RateLimiter limiter = RateLimiter.create(10); //每秒不超过10个任务被提交        limiter.acquire();  //请求RateLimiter, 超过10个会被阻塞        executor.submit(runnable); //提交任务

也可以以非阻塞的形式来使用:

If(limiter.tryAcquire()){ //未请求到limiter则立即返回false    doSomething();}else{    doSomethingElse();}

下面可以看代码测试,通过例子就能理解出原理

    public static void main(String args[]){        //5000当前程序耗时:2007ms        //40000当前程序耗时:259ms        //不加速率当前程序耗时:2ms 如果不限速相当于2毫秒就能处理完,        long startTime=System.currentTimeMillis();        /**         * 每秒的令牌数是10000         * 限速后根据大小,设置的令牌越小,处理速度越慢,设置的令牌数越大,速度越快         */        RateLimiter  rateLimiter = RateLimiter.create(40000);       //rateLimiter.setRate(40000);        //下面是一些测试代码        for(int i=0;i<10000;i++){            rateLimiter.acquire();        }        long endTime=System.currentTimeMillis();        System.out.println("当前程序耗时:"+(endTime-startTime)+"ms");    }

下面是介绍RateLimiter的博客

http://ifeve.com/guava-ratelimiter/

http://blog.csdn.net/cloud_ll/article/details/43602325

http://www.voidcn.com/blog/jiesa/article/p-4943128.html

http://www.jianshu.com/p/3dfae5c15eb9

原创粉丝点击