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

      我们系统现在架构是收到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

你可能感兴趣的:(并发编程)