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
        ......
    }
}
相關文章
相關標籤/搜索