.NET 7 內置了速率限制(Rate Limiting)功能,速率限制指的是限制可訪問資源的請求數。例如數據庫每分鐘可以安全處理 1000 個請求,再多不確定會不會崩。這時就可以在應用程序中放一個速率限制器,規定每分鐘只允許 1000 個請求,在達到這個數量后開始拒絕請求。這是一種保護資源的方法,可以避免應用在高瀏覽的情況下崩潰。
有很多種不同的算法來控制請求流,下面介紹 .NET 7 中提供的 4 種方法:
并發限制
顧名思義,并發限制器就是限制有多少并發請求可以訪問資源。如果限制是 10,那么只有 10 個請求可以同時訪問一個資源,第 11 個請求將被拒絕。
一旦前面的請求完成,則允許的請求數量會增加 1,當第二個請求完成時,數量增加到 2,依此類推。該算法是通過 RateLimitLease 來完成的。
令牌桶
令牌桶是另一種算法,就像一個裝滿令牌的桶。每隔一段時間,桶內會新增固定數量的令牌,但令牌數不能超過桶可容納的最大數量。當一個請求進來時,它會獲取并保存一個令牌,如果存儲桶為空,則新請求進入時沒有令牌可獲取,即將被拒絕訪問資源。
假設單個桶可以容納 10 個令牌,且每分鐘往里面加入 2 個令牌。現在有 3 個請求進來了,剩下 7 個令牌。一分鐘后,桶自動補充到 9 個令牌,然后 9 個請求瞬間取走所有令牌。那么接下來在桶內添加令牌之前,所有請求都不允許訪問資源。如果接下來沒有請求,則桶會在 5 分鐘內自動補到 10 個令牌,然后等待請求。
固定窗口限制
固定窗口算法使用 "窗口" 的概念,窗口采用時間計量,在固定的一段時間內限制最大請求,并在切換到下一個窗口的時候重置請求數。
假設現在有一個最多只能容納 100 人(最大請求數)的電影院(窗口),每場電影需要播放 2 個小時(窗口持續時間)。電影開始后,剩下的觀眾(請求)只能排隊等待下一場窗口,排隊的最大數量也是 100 ,超出的部分不允許繼續排隊,只能等待下一個窗口開始后才能繼續排隊。
滑動窗口限制
滑動窗口算法類似于固定窗口算法,但增加了 "段(segments)" 的概念。
-
一個段是一個窗口的一部分,如果將前面 2 小時的窗口分成 4 個段,則會有 4 個 30 分鐘的段。此外還有一個 "段索引",它始終指向窗口中的最新段。
-
30 分鐘內的請求進入最新的段,且每 30 分鐘窗口滑動一個段。如果在窗口滑過段期間出現了新的請求,則該請求會被刷新,且段的最大限制會增加。如果沒有請求,則段的限制保持不變。
例設現在有一個滑動窗口,它包含 3 個 10 分鐘的段,最多只能接受 100 個請求。現在它的初始狀態是 3 個段,計數均為 0,當前的段索引指向第 3 個段。
Asp.net core中間件
除了基礎API外,也挺了 Microsoft.AspNetCore.RateLimiting 這個中間件可以在asp.net core程序中供我們快速使用,這些都是非常方便了。
更多信息請參看微軟官方文檔:Announcing Rate Limiting for .NET
相關文章:
浙公網安備 33010602011771號