漏桶算法與令牌桶算法在表面看起來類似,很容易將兩者混淆。但事實上,這兩者具有截然不同的特性,且為不同的目的而使用。漏桶算法與令牌桶算法的區別在於:漏桶算法能夠強行限制數據的傳輸速率。令牌桶算法能夠在限制數據的平均傳輸速率的同時還允許某種程度的突發傳輸。需要說明的是:在某些情況下,漏桶算法不能夠有效地使用網絡資源。因為漏桶的漏出速率是固定的,所以即使網絡中沒有發生擁塞,漏桶算法也不能使某一個單獨的數據流達到端口速率。因此,漏桶算法對於存在突發特性的流量來說缺乏效率。而令牌桶算法則能夠滿足這些具有突發特性的流量。通常,漏桶算法與令牌桶算法結合起來為網絡流量提供更高效的控制
漏桶限流算法的原理
以固定速率從桶中流出水滴,以任意速率往桶中放入水滴,桶容量大小是不會發生改變的。
流入:以任意速率往桶中放入水滴。
流出:以固定速率從桶中流出水滴。
水滴:是唯一不重復的標識。
因為桶中的容量是固定的,如果流入水滴的速率>流出的水滴速率,桶中的水滴可能會溢出。那么溢出的水滴請求都是拒絕訪問的,或者直接調用服務降級方法。前提是同一時刻
令牌桶算法(Token)
令牌桶分為2個動作,動作1(固定速率往桶中存入令牌)、動作2(客戶端如果想訪問請求,先從桶中獲取token)。guava 提供的RateLimiter類來進行限流處理。
1.傳統的方式整合RateLimiter 有很大的缺點:代碼重復量特別大,而且本身不支持注解方式。
2.如果限流代碼可以放在網關中,相當於針對所有的服務接口都實現限流(可以使用排除法進行排除不進行限流的方法),維護性不是很強。
3.正常的互聯網公司項目,不是所有的服務接口都需要實現限流方法的,一般只真針對於大流量接口。比如:秒殺搶購、12306搶票等。
4.可以手動封裝一個RateLimiter類 注解來解決這個方法
以規定的速率往令牌桶中放入 token,用戶請求必須獲取到令牌桶中的 token才可以訪問我們的業務邏輯方法,如果沒有從令牌桶中獲取到 token ,拒絕訪問。
在高並發情況下,如果我們的請求過多 超出了令牌桶生成令牌的速度,這時候請求就會被駁回,提示請稍后重試!
優勢:能夠控制請求的速率。
限流的目的:為了保護服務,避免服務宕機
總結
常用的限流算法有兩種:漏桶算法和令牌桶算法。
漏桶算法思路很簡單,水(請求)先進入到漏桶里,漏桶以一定的速度出水,當水流入速度過大會直接溢出,可以看出漏桶算法能強行限制數據的傳輸速率
對於很多應用場景來說,除了要求能夠限制數據的平均傳輸速率外,還要求允許某種程度的突發傳輸。這時候漏桶算法可能就不合適了,令牌桶算法更為適合。如圖2所示,令牌桶算法的原理是系統會以一個恆定的速度往桶里放入令牌,而如果請求需要被處理,則需要先從桶里獲取一個令牌,當桶里沒有令牌可取時,則拒絕服務
並不能說明令牌桶一定比漏洞好,她們使用場景不一樣。令牌桶可以用來保護自己,主要用來對調用者頻率進行限流,為的是讓自己不被打垮。所以如果自己本身有處理能力的時候,如果流量突發(實際消費能力強於配置的流量限制),那么實際處理速率可以超過配置的限制。而漏桶算法,這是用來保護他人,也就是保護他所調用的系統。主要場景是,當調用的第三方系統本身沒有保護機制,或者有流量限制的時候,我們的調用速度不能超過他的限制,由於我們不能更改第三方系統,所以只有在主調方控制。這個時候,即使流量突發,也必須舍棄。因為消費能力是第三方決定的。
總結起來:如果要讓自己的系統不被打垮,用令牌桶。如果保證被別人的系統不被打垮,用漏桶算法