blogs.com/forezp/p/10140316.html
限流要解決的問題
典型限流的應用場景:
如何限流?
壹般網關都有這種功能。 gateway、nginx、zuul等
限流:壹定時間內,只允許N次請求。
從計算機友好的角度出發,是希望能在單位時間內均攤掉請求,使用漏鬥算法可以達到這種效果。
但是漏鬥算法有個弊端,就是先快後慢的這種請求,那麽峰值的請求也只能排隊等待被消費。實際上計算機是具備壹定的高並發處理能力的,只要不是壹直處於高並發下即可。所以 計數器限流和 漏洞限流折中的算法,令牌限流成為現在最主流的算法。
(Redis 結合expire方案可以實現)
第壹次請求開始計時,例如1s以內,達到100次請求就拒絕訪問了,直到1s過後,重新開始計數。
優點:
缺點:短暫的峰值過高對服務器不友好。服務器希望能把請求盡量的均攤開來,這樣可以充分利用計算機資源。
消費的速度是恒定的,對於服務器而言是最友好的。
在算法實現方面,可以準備壹個隊列,用來保存請求,另外通過壹個線程池(ScheduledExecutorService)來定期從隊列中獲取請求並執行,可以壹次性獲取多個並發執行。
參數:消費速度、桶容量(超過就拋棄,可以避免內存過大,有過多的等待的任務)
優點:
缺點:
令牌桶算法是比較常見的限流算法之壹,大概描述如下:
1)所有的請求在處理之前都需要拿到壹個可用的令牌才會被處理;
2)根據限流大小,設置按照壹定的速率往桶裏添加令牌;
3)桶設置最大的放置令牌限制,當桶滿時、新添加的令牌就被丟棄活著拒絕;
4)請求達到後首先要獲取令牌桶中的令牌,拿著令牌才可以進行其他的業務邏輯,處理完業務邏輯之後,將令牌直接刪除;
5)令牌桶有最低限額,當桶中的令牌達到最低限額的時候,請求處理完之後將不會刪除令牌,以此保證足夠的限流;
這種算法,既可以保證系統由壹定的高並發能力,比如當前令牌桶容量是100,壹開始直接消費掉100個請求。有保證服務器不會因為短暫的爆發,而導致server端空閑,因為令牌桶還會持續的生產令牌。
既有壹定的並發能力,又不至於完全失去控制,可控的兼具並發力和流量控制的限流算法.是計數器算法(壹定的並發處理能力)和漏洞限流(高峰過後仍然會持續的產生令牌)的折中算法。