錯誤使用
在實現限流時,網上的各種文章基本都會提到Guava的RateLimiter,用於實現單機的限流,並給出類似的代碼:
public void method() {
RateLimiter rateLimiter = RateLimiter.create(10);
if(rateLimiter.tryAcquire()){
// do business
......
}
}
可是上面的代碼真的能限流嗎?
首先,從代碼邏輯角度來講,方法在每次被調用是都new一個RateLimiter,不同請求之間毫無關聯,怎么能起到限流的作用呢?
其次,經過本人實際驗證,上面的方法運行結果表明,根本沒有限流的作用。
正確使用
在SpringMVC項目中,controller、service等對應的bean都是單例,因此將RateLimiter作為bean的屬性並初始化,再加上RateLimiter的注釋中表示RateLimiter是並發安全的:
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.
因此,正確的寫法如下:
private RateLimiter rateLimiter = RateLimiter.create(10);
public void method() {
if(rateLimiter.tryAcquire()){
// do business
......
}
}
