ASP.NET Core中使用令牌桶限流的實現

在限流時一般會限制每秒或每分鐘的請求數,簡單點一般會采用計數器算法,這種算法實現相對簡單,也很高效,但是無法應對瞬時的突發流量。

比如限流每秒100次請求,絕大多數的時間裡都不會超過這個數,但是偶爾某一秒鐘會達到120次請求,接著很快又會恢復正常,假設這種突發的流量不會對系統穩定性帶來實質性的影響,則可以在一定程度上允許這種瞬時的突發流量,從而為用戶帶來更好的可用性體驗。這就是令牌桶算法的用武之地。

該算法的基本原理是:有一個令牌桶,容量是X,每Y單位時間會向桶中放入Z個令牌,如果桶中的令牌數超過X,則丟棄令牌;請求要想通過首先需要從令牌桶中獲取一個令牌,獲取不到令牌則拒絕請求。可以看出對於令牌桶算法X、Y、Z這幾個數的設定特別重要,Z應該略大於絕大數時候的Y單位時間內的請求數,系統會長期處於這個狀態,X可以是系統允許承載的瞬時最大請求數,系統不能長時間處於這個狀態。

這裡介紹一個ASP.NET Core的中間件來滿足令牌桶限流需求: FireflySoft.RateLimit.AspNetCore 。使用步驟如下:

1、安裝Nuget包

有多種安裝方式,選擇自己喜歡的就行瞭。

包管理器命令:

Install-Package FireflySoft.RateLimit.AspNetCore

或者.NET命令:

dotnet add package FireflySoft.RateLimit.AspNetCore

或者項目文件直接添加:

<ItemGroup>
<PackageReference Include="FireflySoft.RateLimit.AspNetCore" Version="2.*" />
</ItemGroup>

2、使用中間件

在Startup中使用中間件,演示代碼如下(下邊會有詳細說明):

public void ConfigureServices(IServiceCollection services)
        {
            ...
            app.AddRateLimit(new InProcessTokenBucketAlgorithm(
                new[] {
                    new TokenBucketRule(30,10,TimeSpan.FromSeconds(1))
                    {
                        ExtractTarget = context =>
                        {
                            return (context as HttpContext).Request.Path.Value;
                        },
                        CheckRuleMatching = context =>
                        {
                            return true;
                        },
                        Name="default limit rule",
                    }
                })
            );
            ...
        }

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            ...
            app.UseRateLimit();
            ...
        }

如上需要先註冊服務,然後使用中間件。

註冊服務的時候需要提供限流算法和對應的規則:

  • 這裡使用進程內令牌桶算法,對於分佈式服務還可以使用Redis令牌桶算法,支持StackExchange.Redis。
  • 桶的容量是30,每秒流入10個令牌。
  • ExtractTarget用於提取限流目標,這裡是每個不同的請求Path。如果有IO請求,這裡還支持對應的異步方法ExtractTargetAsync。
  • CheckRuleMatching用於驗證當前請求是否限流。如果有IO請求,這裡還支持對應的異步方法CheckRuleMatchingAsync。
  • 默認被限流時會返回HttpStatusCode 429,可以在AddRateLimit時使用可選參數error自定義這個值,以及Http Header和Body中的內容。
  • 基本的使用就是上邊例子中的這些瞭。

另外這個項目也支持.Net Framework,需要安裝另一個包 FireflySoft.RateLimit.AspNet ,如果你的程序基於.net 4.x,可以選擇這個版本。

同時在非Web應用場景也有對應的包支持: FireflySoft.RateLimit.Core ,隻不過需要自己處理限流結果。

他們的使用方法都很類似,邏輯也很簡單,都是需要先創建一個算法實例,然後通過這個實例去檢查每一次請求,根據業務需要處理檢查結果就可以瞭。

到此這篇關於ASP.NET Core中使用令牌桶限流的實現的文章就介紹到這瞭,更多相關ASP.NET Core中使用令牌桶限流內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀:

    None Found