当前位置:网站首页>. Net service governance flow limiting middleware -fireflysoft RateLimit

. Net service governance flow limiting middleware -fireflysoft RateLimit

2022-07-05 07:45:00 Persian horse

summary

FireflySoft.RateLimit since 2021 year 1 Since the first release in June , Experienced many upgrade iterations , At present, it has been very stable , It has been applied to the production system by many developers , The latest release is 3.0.0.

Its core is based on .NET Standard Current limiting class library , Its core is simple and lightweight , Current limiting scenarios that can flexibly respond to various needs . Its main features include :

  • Various current limiting algorithms : Built in fixed window 、 The sliding window 、 Leaky bucket 、 There are four algorithms for token bucket , Easy to customize and expand .
  • Multiple count storage : Memory is currently supported 、Redis( Including clusters ) Two ways of storage .
  • Distributed friendly : adopt Redis Storage supports unified counting of distributed programs .
  • The current limiting target is flexible : Various data can be extracted from the request to set the current limiting target , Not just the client IP and Id.
  • Current limiting penalty is supported : You can lock the client for a period of time after triggering the current limit and not allow it to access .
  • Time window enhancement : Support to the millisecond level ; Support from seconds 、 minute 、 Hours 、 The natural starting point of a time cycle, such as a date .
  • Real time current limit tracking : The number of requests processed in the current counting cycle 、 Number of remaining allowed requests , And the reset time of the counting cycle .
  • Change rules dynamically : Support the dynamic change of current limiting rules when the program is running .
  • Custom error : You can customize the error code and error message after triggering current limiting .
  • Universality : In principle, it can meet any current limiting scenario , It can be used in all kinds of B/S、C/S Program .

Based on this core, two middleware are implemented :

Compared with FireflySoft.RateLimit The core library , It is more convenient to use these two middleware directly . If these two middleware cannot meet your needs , For example, it is not used in official Web In the frame , Not even Web Program , No big problem , It can meet your current limiting needs based on the core class library , All you have to do is define the request you want to limit the flow , And execute its own business logic when triggering current limit , How to implement the current limiting algorithm does not need to be concerned .

These class libraries and middleware are available through Nuget Installed , Search for  FireflySoft.RateLimit  You can find it .

Examples of use

This article is based on a ASP.NET Core Program, for example , explain FireflySoft.RateLimit How to use .

The business requirements of the program are : Interface for obtaining weather forecast , According to client IP and ClientId Carry out current limiting , Every IP Every second 1 Time , Every ClientId Every second 3 Time .ClientId Is pre assigned to the caller . According to rules , If the caller has only 1 An exit IP, Then you can only access 1 Time , If there are multiple exits IP, Then visit at most per second 3 Time .

This sample program is based on .NET6 Developed , Of course you use .NET Core 3.1 No problem , It's just .NET6 By default, the service and middleware registration are put in Program.cs  in .( It is recommended to upgrade to .NET6,.NET6 comparison .NET Core 3.1 The performance of has been significantly improved .)

Look at the code it , Just register the service and Middleware That's all right. .

using FireflySoft.RateLimit.AspNetCore;
using FireflySoft.RateLimit.Core.InProcessAlgorithm;
using FireflySoft.RateLimit.Core.Rule;

var builder = WebApplication.CreateBuilder(args);

...

builder.Services.AddRateLimit(new InProcessFixedWindowAlgorithm(
    new[] {
        new FixedWindowRule()
        {
            ExtractTarget = context =>
            {
                var httpContext= context as HttpContext;

                // Through CDN
                var ip = httpContext!.Request.Headers["Cdn-Src-Ip"].FirstOrDefault();
                if (!string.IsNullOrEmpty(ip))
                    return ip;

                // Through SLB
                ip = httpContext!.Request.Headers["X-Forwarded-For"].FirstOrDefault();
                if (!string.IsNullOrEmpty(ip))
                    return ip;

                ip = httpContext!.Connection.RemoteIpAddress?.ToString();
                return ip??"Anonymous-IP";
            },
            CheckRuleMatching = context =>
            {
                var requestPath = (context as HttpContext)!.Request.Path.Value;
                if (requestPath == "/WeatherForecast/Future")
                {
                    return true;
                }
                return false;
            },
            Name = "ClientIPRule",
            LimitNumber = 3,
            StatWindow = TimeSpan.FromSeconds(1)
        },
        new FixedWindowRule()
        {
            ExtractTarget = context =>
            {
                var httpContext= context as HttpContext;
                var clientID = httpContext!.Request.Headers["X-ClientId"].FirstOrDefault();

                return clientID??"Anonymous-ClientId";
            },
            CheckRuleMatching = context =>
            {
                var requestPath = (context as HttpContext)!.Request.Path.Value;
                if (requestPath == "/WeatherForecast/Future")
                {
                    return true;
                }
                return false;
            },
            Name = "ClientIdRule",
            LimitNumber = 1,
            StatWindow = TimeSpan.FromSeconds(1)
        }
    })
);

...

app.UseRateLimit();

...

Only the content required by the middleware is retained in the pasted code , The registration service uses AddRateLimit, Use middleware to pass UseRateLimit.

Algorithm

AddRateLimit You need to specify a current limiting Algorithm , The example is a fixed window algorithm based on local memory , It can be replaced with other algorithms as needed , For example, token bucket algorithm that can deal with short-term burst traffic .

For a specific algorithm , Based on local memory and based on Redis The implementation of is a different class , Because for better performance ,Redis The algorithm is implemented by Lua It's scripted , It runs completely in Redis Server side .

For ease of use , List the names of these algorithms here :

Based on local memory ( In process ) be based on Redis
Fixed window algorithm InProcessFixedWindowAlgorithmRedisFixedWindowAlgorithm
Sliding window algorithm InProcessSlidingWindowAlgorithmRedisSlidingWindowAlgorithm
Leaky bucket algorithm InProcessFixedWindowAlgorithmRedisFixedWindowAlgorithm
Token bucket algorithm InProcessTokenBucketAlgorithmRedisokenBucketAlgorithm

At present one ASP.NET Core Only one algorithm can be used in the program , I don't know whether there is a need for multiple algorithms , If necessary, you can FireflySoft.RateLimit.AspNetCore Make some changes :

  • AddRateLimit Sign up for IAlgorithm Change to register IAlgorithm The parser , The parser provides a method based on a Key return IAlgorithm The concrete realization of .

  • RateLimitMiddleware Determine the algorithm to be used according to the current request , Then call the method of the parser to get IAlgorithm The concrete realization of .

The rules

When creating algorithm instances , You also need to specify the rules of the algorithm , The algorithm used here is FixedWindowRule, For the same algorithm , In process implementation and Redis The implementation uses the same rules .

Take a look at several properties of the rules used here :

ExtractTarget  Set up a function , For from HTTP Extract the target to limit the flow in the request , For example, the client here IP And the client ID, It can also be all kinds of things that can be extracted from or associated with the request , such as Http Header Users carried in Id, Or according to the user Id The age of the user queried .

CheckRuleMatching  Set up a function , Returns whether the current request can match a flow restriction rule , If you can match , Then return to true. For example, only /api/req This path limits current , Then just judge that the path of the request is it , Just go back to true, All other paths return false. Of course, it can also be judged according to various things that can be extracted or associated from the request .

Name  The name of the current limit rule , It is convenient for people to distinguish when tracking .

StatWindow  Time window for current limiting . For example, every second in the demand 3 Time , The time window here should be set to 1 second .

LimitNumber  The number threshold of current limiting . For example, every second in the demand 3 Time , The time window here should be set to 3, exceed 3 It will be limited .

There are several other attributes in the rule , The rules of different algorithms are also slightly different , Here is not a list . Interested friends can go Sample code and unit testing Know them in .

Rules of multiple corresponding algorithms can be added to an algorithm , This will undoubtedly be more flexible .

More instructions


The above is the main content of this paper , If you have any questions, please leave a message .

原网站

版权声明
本文为[Persian horse]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/186/202207050739423986.html