<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Asp.NET Core 限流控制-AspNetCoreRateLimit

          共 8656字,需瀏覽 18分鐘

           ·

          2021-03-05 18:56

          起因:

           近期項(xiàng)目中,提供了一些調(diào)用頻率較高的api接口,需要保障服務(wù)器的穩(wěn)定運(yùn)行;需要對(duì)提供的接口進(jìn)行限流控制。避免因客戶端頻繁的請(qǐng)求導(dǎo)致服務(wù)器的壓力。

          一、AspNetCoreRateLimit 介紹

           AspNetCoreRateLimit是一個(gè)ASP.NET Core速率限制的解決方案,旨在控制客戶端根據(jù)IP地址或客戶端ID向Web API或MVC應(yīng)用發(fā)出的請(qǐng)求的速率。AspNetCoreRateLimit包含一個(gè)IpRateLimitMiddlewareClientRateLimitMiddleware,每個(gè)中間件可以根據(jù)不同的場(chǎng)景配置限制允許IP或客戶端,自定義這些限制策略,也可以將限制策略應(yīng)用在每個(gè)API URL或具體的HTTP Method上。

          二、AspNetCoreRateLimit使用

           由上面介紹可知AspNetCoreRateLimit支持了兩種方式:基于客戶端IP(IpRateLimitMiddleware)和客戶端ID(ClientRateLimitMiddleware)速率限制 接下來就分別說明使用方式

           添加Nuget包引用:

           Install-Package AspNetCoreRateLimit
          • 基于客戶端IP速率限制

            1、修改Startup.cs中方法:

          public class Startup
          {
          public Startup(IConfiguration configuration)
          {
          Configuration
          = configuration;
          }

          public IConfiguration Configuration { get; }// This method gets called by the runtime. Use this method to add services to the container.
          public void ConfigureServices(IServiceCollection services)
          {
          //需要從加載配置文件appsettings.json
          services.AddOptions();
          //需要存儲(chǔ)速率限制計(jì)算器和ip規(guī)則
          services.AddMemoryCache();

          //從appsettings.json中加載常規(guī)配置,IpRateLimiting與配置文件中節(jié)點(diǎn)對(duì)應(yīng)
          services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));

          //從appsettings.json中加載Ip規(guī)則
          services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies"));

          //注入計(jì)數(shù)器和規(guī)則存儲(chǔ)
          services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
          services.AddSingleton
          <IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();

          services.AddControllers();

          services.AddSingleton
          <IHttpContextAccessor, HttpContextAccessor>();
          //配置(解析器、計(jì)數(shù)器密鑰生成器)
          services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();

          //Other Code
          }

          // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
          {
          //Other Code

          app.UseRouting();

          app.UseAuthorization();
               //啟用客戶端IP限制速率
          app.UseIpRateLimiting();

          app.UseEndpoints(endpoints
          =>
          {
          endpoints.MapControllers();
          });
          }
          }

            2、在appsettings.json中添加通用配置項(xiàng)節(jié)點(diǎn):(IpRateLimiting節(jié)點(diǎn)與Startup中取的節(jié)點(diǎn)對(duì)應(yīng))

          "IpRateLimiting": {
          //false,則全局將應(yīng)用限制,并且僅應(yīng)用具有作為端點(diǎn)的規(guī)則*。例如,如果您設(shè)置每秒5次調(diào)用的限制,則對(duì)任何端點(diǎn)的任何HTTP調(diào)用都將計(jì)入該限制
          //true, 則限制將應(yīng)用于每個(gè)端點(diǎn),如{HTTP_Verb}{PATH}。例如,如果您為*:/api/values客戶端設(shè)置每秒5個(gè)呼叫的限制,
          "EnableEndpointRateLimiting": false,
          //false,拒絕的API調(diào)用不會(huì)添加到調(diào)用次數(shù)計(jì)數(shù)器上;如 客戶端每秒發(fā)出3個(gè)請(qǐng)求并且您設(shè)置了每秒一個(gè)調(diào)用的限制,則每分鐘或每天計(jì)數(shù)器等其他限制將僅記錄第一個(gè)調(diào)用,即成功的API調(diào)用。如果您希望被拒絕的API調(diào)用計(jì)入其他時(shí)間的顯示(分鐘,小時(shí)等)
          //,則必須設(shè)置StackBlockedRequests為true。

          "StackBlockedRequests": false,
          //Kestrel 服務(wù)器背后是一個(gè)反向代理,如果你的代理服務(wù)器使用不同的頁眉然后提取客戶端IP X-Real-IP使用此選項(xiàng)來設(shè)置
          "RealIpHeader": "X-Real-IP",
          //取白名單的客戶端ID。如果此標(biāo)頭中存在客戶端ID并且與ClientWhitelist中指定的值匹配,則不應(yīng)用速率限制。
          "ClientIdHeader": "X-ClientId",
          //限制狀態(tài)碼
          "HttpStatusCode": 429,
          ////IP白名單:支持Ip v4和v6
          //"IpWhitelist": [ "127.0.0.1", "::1/10", "192.168.0.0/24" ],
          ////端點(diǎn)白名單
          //"EndpointWhitelist": [ "get:/api/license", "*:/api/status" ],
          ////客戶端白名單
          //"ClientWhitelist": [ "dev-id-1", "dev-id-2" ],
          //通用規(guī)則
          "GeneralRules": [
          {
          //端點(diǎn)路徑
          "Endpoint": "*",
          //時(shí)間段,格式:{數(shù)字}{單位};可使用單位:s, m, h, d
          "Period": "1s",
          //限制
          "Limit": 2
          },
             //15分鐘只能調(diào)用100次
          {
          "Endpoint": "*","Period": "15m","Limit": 100},
             //12H只能調(diào)用1000
          {
          "Endpoint": "*","Period": "12h","Limit": 1000},
             //7天只能調(diào)用10000次
          {
          "Endpoint": "*","Period": "7d","Limit": 10000}
          ]
          }

             配置節(jié)點(diǎn)已添加相應(yīng)注釋信息。

             規(guī)則設(shè)置格式:   

          端點(diǎn)格式:{HTTP_Verb}:{PATH},您可以使用asterix符號(hào)來定位任何HTTP謂詞。

          期間格式:{INT}{PERIOD_TYPE},您可以使用以下期間類型之一:s, m, h, d

          限制格式:{LONG}

            3、特點(diǎn)Ip限制規(guī)則設(shè)置,在appsettings.json中添加 IP規(guī)則配置節(jié)點(diǎn)

          "IpRateLimitPolicies": {
          //ip規(guī)則
          "IpRules": [
          {
          //IP
          "Ip": "84.247.85.224",
          //規(guī)則內(nèi)容
          "Rules": [
          //1s請(qǐng)求10次
          {"Endpoint": "*","Period": "1s","Limit": 10},
          //15分鐘請(qǐng)求200次
          {"Endpoint": "*","Period": "15m","Limit": 200}
          ]
          },
          {
          //ip支持設(shè)置多個(gè)
          "Ip": "192.168.3.22/25",
          "Rules": [
          //1秒請(qǐng)求5次
          {"Endpoint": "*","Period": "1s","Limit": 5},
          //15分鐘請(qǐng)求150次
          {"Endpoint": "*","Period": "15m","Limit": 150},
          //12小時(shí)請(qǐng)求500次
          {"Endpoint": "*","Period": "12h","Limit": 500}
          ]
          }
          ]
          }

          • 基于客戶端ID速率限制

            1、修改Startup文件:

          public void ConfigureServices(IServiceCollection services)
          {
          //需要從加載配置文件appsettings.json
          services.AddOptions();

          //需要存儲(chǔ)速率限制計(jì)算器和ip規(guī)則
          services.AddMemoryCache();

          //從appsettings.json中加載常規(guī)配置
          services.Configure<ClientRateLimitOptions>(Configuration.GetSection("IPRateLimiting"));

          //從appsettings.json中加載客戶端規(guī)則
          services.Configure<ClientRateLimitPolicies>(Configuration.GetSection("ClientRateLimitPolicies"));

          //注入計(jì)數(shù)器和規(guī)則存儲(chǔ)
          services.AddSingleton<IClientPolicyStore, MemoryCacheClientPolicyStore>();
          services.AddSingleton
          <IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();


          services.AddControllers();

          // https://github.com/aspnet/Hosting/issues/793
          // the IHttpContextAccessor service is not registered by default.
          //注入計(jì)數(shù)器和規(guī)則存儲(chǔ)
          services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

          //配置(解析器、計(jì)數(shù)器密鑰生成器)
          services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
          }

          public void Configure(IApplicationBuilder app, IHostingEnvironment env)
          {
          //啟用客戶端限制
          app.UseClientRateLimiting();

          app.UseMvc();
          }

            2、通用配置采用IP限制相同配置,添加客戶端限制配置:

          //客戶端限制設(shè)置
          "ClientRateLimitPolicies": {
          "ClientRules": [
          {
          //客戶端id
          "ClientId": "client-id-1",
          "Rules": [
          {
          "Endpoint": "*","Period": "1s","Limit": 10},
          {
          "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}
          ]
          }
          ]
          }

            3、調(diào)用結(jié)果:

              設(shè)置規(guī)則:1s只能調(diào)用一次:首次調(diào)用

              

               調(diào)用第二次:自定義返回內(nèi)容

               

          三、其他 

          • 運(yùn)行時(shí)更新速率限制

             添加IpRateLimitController控制器:   

          /// <summary>
          /// IP限制控制器
          /// </summary>
          [Route("api/[controller]")]
          [ApiController]
          public class IpRateLimitController : ControllerBase
          {

          private readonly IpRateLimitOptions _options;
          private readonly IIpPolicyStore _ipPolicyStore;

          /// <summary>
          ///
          /// </summary>
          /// <param name="optionsAccessor"></param>
          /// <param name="ipPolicyStore"></param>
          public IpRateLimitController(IOptions<IpRateLimitOptions> optionsAccessor, IIpPolicyStore ipPolicyStore)
          {
          _options
          = optionsAccessor.Value;
          _ipPolicyStore
          = ipPolicyStore;
          }

          /// <summary>
          /// 獲取限制規(guī)則
          /// </summary>
          /// <returns></returns>
          [HttpGet]
          public async Task<IpRateLimitPolicies> Get()
          {
          return await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix);
          }

          /// <summary>
          ///
          /// </summary>
          [HttpPost]
          public async Task Post(IpRateLimitPolicy ipRate)
          {
          var pol = await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix);
          if (ipRate != null)
          {

          pol.IpRules.Add(ipRate);
          await _ipPolicyStore.SetAsync(_options.IpPolicyPrefix, pol);
          }
          }
          }

          • 分布式部署時(shí),需要將速率限制計(jì)算器和ip規(guī)則存儲(chǔ)到分布式緩存中如Redis

            • 修改注入對(duì)象

          // inject counter and rules distributed cache stores
          services.AddSingleton<IClientPolicyStore, DistributedCacheClientPolicyStore>();
          services.AddSingleton
          <IRateLimitCounterStore,DistributedCacheRateLimitCounterStore>();

            • 添加Nuget包 Microsoft.Extensions.Caching.StackExchangeRedis 

            • 在Startup中設(shè)置Redis連接

          services.AddStackExchangeRedisCache(options =>
          {
          options.ConfigurationOptions
          = new ConfigurationOptions
          {
          //silently retry in the background if the Redis connection is temporarily down
          AbortOnConnectFail = false
          };
          options.Configuration
          = "localhost:6379";
          options.InstanceName
          = "AspNetRateLimit";
          });

          • 限制時(shí)自定義相應(yīng)結(jié)果:

            //請(qǐng)求返回
            "QuotaExceededResponse": {
            "Content": "{{\"code\":429,\"msg\":\"Visit too frequently, please try again later\",\"data\":null}}",
            "ContentType": "application/json;utf-8",
            "StatusCode": 429
            },

               調(diào)用時(shí)返回結(jié)果:

          其他:

            示例代碼:https://github.com/cwsheng/WebAPIVersionDemo


          往期精彩回顧




          【推薦】.NET Core開發(fā)實(shí)戰(zhàn)視頻課程 ★★★

          .NET Core實(shí)戰(zhàn)項(xiàng)目之CMS 第一章 入門篇-開篇及總體規(guī)劃

          【.NET Core微服務(wù)實(shí)戰(zhàn)-統(tǒng)一身份認(rèn)證】開篇及目錄索引

          Redis基本使用及百億數(shù)據(jù)量中的使用技巧分享(附視頻地址及觀看指南)

          .NET Core中的一個(gè)接口多種實(shí)現(xiàn)的依賴注入與動(dòng)態(tài)選擇看這篇就夠了

          10個(gè)小技巧助您寫出高性能的ASP.NET Core代碼

          用abp vNext快速開發(fā)Quartz.NET定時(shí)任務(wù)管理界面

          在ASP.NET Core中創(chuàng)建基于Quartz.NET托管服務(wù)輕松實(shí)現(xiàn)作業(yè)調(diào)度

          現(xiàn)身說法:實(shí)際業(yè)務(wù)出發(fā)分析百億數(shù)據(jù)量下的多表查詢優(yōu)化

          關(guān)于C#異步編程你應(yīng)該了解的幾點(diǎn)建議

          C#異步編程看這篇就夠了


          瀏覽 65
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  激情五月天激情网 | 日韩无码啪啪啪 | 尻屄视频在线播放 | 午夜男女啪啪网站 | 欧美在线视频网站 |