Implementation of token bucket current limiting in ASP. NET Core

  • 2021-11-29 06:42:44
  • OfStack

When limiting current, 1 will limit the number of requests per second or minute, and simple point 1 will adopt counter algorithm, which is relatively simple and efficient, but cannot cope with instantaneous burst traffic.

For example, limiting the current to 100 requests per second, Most of the time, it will not exceed this number, but occasionally it will reach 120 requests in one second, and then it will soon return to normal. Assuming that this sudden traffic will not have a substantial impact on the stability of the system, this instantaneous sudden traffic can be allowed to a certain extent, thus bringing better usability experience to users. This is where the token bucket algorithm comes into play.

The basic principle of the algorithm is: there is a token bucket with a capacity of X, Z tokens will be put into the bucket every Y unit time, and if the number of tokens in the bucket exceeds X, the tokens will be discarded; If the request wants to pass, it needs to get 1 token from the token bucket first, and reject the request if it can't get the token. It can be seen that the setting of token bucket algorithms X, Y and Z is particularly important. Z should be slightly larger than the number of requests per unit time of Y in most cases, and the system will be in this state for a long time. X can be the instantaneous maximum number of requests allowed by the system, and the system cannot be in this state for a long time.

Here is a middleware of ASP. NET Core to meet the token bucket current limiting requirements: FireflySoft. RateLimit. AspNetCore. The steps are as follows:

1. Install the Nuget package

There are many installation methods, just choose the one you like.

Package Manager Command:


Install-Package FireflySoft.RateLimit.AspNetCore

Or. NET command:


dotnet add package FireflySoft.RateLimit.AspNetCore

Or add the project file directly:


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

2. Using middleware

Using middleware in Startup, the demo code is as follows (described in detail below):


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();
            ...
        }

As above, you need to register the service first, and then use middleware.

When registering a service, you need to provide a current limiting algorithm and corresponding rules:

In-process token bucket algorithm is used here. For distributed services, Redis token bucket algorithm can also be used to support StackExchange. Redis. The capacity of the bucket is 30, and 10 tokens flow in every second. ExtractTarget is used to extract the current limiting target, here for each different request Path. If there is an IO request, the corresponding asynchronous method ExtractTargetAsync is also supported here. CheckRuleMatching is used to verify whether the current request is current-limited. If there is an IO request, the corresponding asynchronous method CheckRuleMatchingAsync is also supported here. By default, HttpStatusCode 429 is returned when current is limited, which can be customized with the optional parameter error when AddRateLimit, as well as the contents of Http, Header and Body. The basic uses are those in the above examples.

In addition, this project also supports. Net Framework, and another package FireflySoft. RateLimit. AspNet needs to be installed. If your program is based on. net 4. x, you can choose this version.

At the same time, there is corresponding package support in non-Web application scenarios: FireflySoft. RateLimit. Core, but you need to handle the current limiting results by yourself.

Their usage methods are very similar, and their logic is very simple. They all need to create an algorithm instance first, then check every request through this instance, and process the check results according to business needs.


Related articles: