在實現限流時,網上的各類文章基本都會提到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 ...... } }