.NET6之MiniAPI(二十一):限流

发布一下 0 0

限流,可以在基础设施进行配置实现,也可以在网关的地方进行限流,但服务本身的限流也不可或缺,因为当多副本时,一个副本故障,流量对于其他副本来说会提高,如果超过其承受请求量的范围,会引起服务连续崩塌,所以单服务本身最好也是要实现限流的。

在asp.net core项目中,可以引入AspNetCoreRateLimit进行限流处理。

可以通过如下方式引入NuGet包

Install-Package AspNetCoreRateLimit

Client限流

using AspNetCoreRateLimit;var builder = WebApplication.CreateBuilder(args);// 注入内存缓存服务builder.Services.AddMemoryCache();//加载ClientRateLimiting配置文件builder.Services.Configure<ClientRateLimitOptions>(builder.Configuration.GetSection("ClientRateLimiting"));//加载ClientRateLimitPolicies配置文件builder.Services.Configure<ClientRateLimitPolicies>(builder.Configuration.GetSection("ClientRateLimitPolicies"));// 注入限流内存缓存服务builder.Services.AddInMemoryRateLimiting();// 注入限流配置文件服务builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();var app = builder.Build();//启用ClientRateLimitPoliciesvar clientPolicyStore = app.Services.GetRequiredService<IClientPolicyStore>();await clientPolicyStore.SeedAsync();//使用Client限流中间件app.UseClientRateLimiting();app.MapGet("/test00", () =>{    return "get test00 ok";});app.MapGet("/test01", () =>{    return "get test01 ok";});app.MapGet("/test02", () =>{    return "get test02 ok";});app.MapPost("/test02", () =>{    return "post test02 ok";});app.Run();

appsetings.json

{  "Logging": {    "LogLevel": {      "Default": "Information",      "Microsoft.AspNetCore": "Warning"    }  },  "AllowedHosts": "*",  "ClientRateLimiting": {    "EnableEndpointRateLimiting": false,    "StackBlockedRequests": false,    "ClientIdHeader": "X-ClientId",    "HttpStatusCode": 429,    "EndpointWhitelist": [ "get:/test00", "*:/test01" ],    "ClientWhitelist": [ "dev-id-1", "dev-id-2" ],    "GeneralRules": [      {        "Endpoint": "*",        "Period": "5s",        "Limit": 2      },      {        "Endpoint": "*",        "Period": "10s",        "Limit": 3      }          ]  },   "ClientRateLimitPolicies": {    "ClientRules": [      {        "ClientId": "client-id-1",        "Rules": [          {            "Endpoint": "*",            "Period": "5s",            "Limit": 1          },          {            "Endpoint": "*",            "Period": "15m",            "Limit": 200          }        ]      },      {        "ClientId": "client-id-2",        "Rules": [          {            "Endpoint": "*",            "Period": "1s",            "Limit": 5          },          {            "Endpoint": "*",            "Period": "15m",            "Limit": 150          },          {            "Endpoint": "*",            "Period": "12h",            "Limit": 500          }        ]      }    ]  }}

配置说明:

EnableEndpointRateLimiting为false全部请求总次数超过阈值,即限流,EnableEndpointRateLimiting为true时,各个请求单次超过阈值即限流

StackBlockedRequests为false时,如果前5s请求了2个成功,1个失败,那第6s后还可以请求一个成功,如果这StackBlockedRequests为true时,那第6s的请求是不能成功的,也就是带不带拒绝的请求

      {        "Endpoint": "*",        "Period": "5s",        "Limit": 2      },      {        "Endpoint": "*",        "Period": "10s",        "Limit": 3      },

ClientIdHeader指定可以通过Header键为X-ClientId处理限流黑白名单

ClientWhitelist值为dev-id-1,dev-id-2,指Header里X-ClientId只要是其中的值 ,就放行

EndpointWhitelist不参与限流的终节点

HttpStatusCode限流后返回的状态码

GeneralRules通用限流规则

ClientRateLimitPolicies 配置是专门为了对不同的X-ClientId进行不同的限流配置,这样可以有区别的来分配流程,而不是一概而论,可以说是ClientId的灰名单,有限流的访问

不但可以通过ClientID限流,还可以是客户请示Ip来限流,配置雷同。

IP限流

using AspNetCoreRateLimit;var builder = WebApplication.CreateBuilder(args);// 注入内存缓存服务builder.Services.AddMemoryCache();//加载IPRateLimiting配置文件builder.Services.Configure<IpRateLimitOptions>(builder.Configuration.GetSection("IpRateLimiting"));//加载IPRateLimitPolicies配置文件builder.Services.Configure<IpRateLimitPolicies>(builder.Configuration.GetSection("IpRateLimitPolicies"));// 注入限流内存缓存服务builder.Services.AddInMemoryRateLimiting();// 注入限流配置文件服务builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();var app = builder.Build();//启用IPRateLimitPoliciesvar ipPolicyStore = app.Services.GetRequiredService<IIpPolicyStore>();await ipPolicyStore.SeedAsync();//使用Ip限流中间件app.UseIpRateLimiting();app.MapGet("/test00", () =>{    return "get test00 ok";});app.MapGet("/test01", () =>{    return "get test01 ok";});app.MapGet("/test02", () =>{    return "get test02 ok";});app.MapPost("/test02", () =>{    return "post test02 ok";});app.MapGet("/test03", () =>{    return "get test01 ok";});app.Run();


appsettings.json

{  "Logging": {    "LogLevel": {      "Default": "Information",      "Microsoft.AspNetCore": "Warning"    }  },  "AllowedHosts": "*",  "IpRateLimiting": {    "EnableEndpointRateLimiting": false,    "StackBlockedRequests": false,    "RealIpHeader": "X-Real-IP",    "IpWhitelist": [ "127.0.0.1"],    "ClientIdHeader": "X-ClientId",    "HttpStatusCode": 429,    "EndpointWhitelist": [ "get:/test00", "*:/test01" ],    "ClientWhitelist": [ "dev-id-1", "dev-id-2" ],    "GeneralRules": [      {        "Endpoint": "*",        "Period": "5s",        "Limit": 2      },      {        "Endpoint": "*",        "Period": "10s",        "Limit": 3      }         ]  },  "IpRateLimitPolicies": {    "IpRules": [      {        "Ip": "127.0.0.2",        "Rules": [          {            "Endpoint": "*",            "Period": "4s",            "Limit": 1          },          {            "Endpoint": "*",            "Period": "15m",            "Limit": 200          }        ]      }         ]  }}

版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除

本文地址:http://0561fc.cn/74783.html