Guava的RateLimiter在单机限流中的正确用法

错误使用

在实现限流时,网上的各类文章基本都会提到Guava的RateLimiter,用于实现单机的限流,并给出相似的代码:安全

public void method() {
    RateLimiter rateLimiter = RateLimiter.create(10);
    if(rateLimiter.tryAcquire()){
        // do business
        ......
    }
}

但是上面的代码真的能限流吗?并发

首先,从代码逻辑角度来说,方法在每次被调用是都new一个RateLimiter,不一样请求之间毫无关联,怎么能起到限流的做用呢?ui

其次,通过本人实际验证,上面的方法运行结果代表,根本没有限流的做用。rest

正确使用

在SpringMVC项目中,controller、service等对应的bean都是单例,所以将RateLimiter做为bean的属性并初始化,再加上RateLimiter的注释中表示RateLimiter是并发安全的:code

RateLimiter is safe for concurrent use: It will restrict the total rate of calls from all threads. Note, however, that it does not guarantee fairness.it

所以,正确的写法以下:thread

private RateLimiter rateLimiter = RateLimiter.create(10);

public void method() {
    if(rateLimiter.tryAcquire()){
        // do business
        ......
    }
}
相关文章
相关标签/搜索