.NET Core WebApi接口ip限流实践

  • .NET Core WebApi接口ip限流实践已关闭评论
  • 121 次浏览
  • A+
所属分类:.NET技术
摘要

之前一直想实现接口限流,但一直没去实现,然后刚好看到一篇文章是基于AspNetCoreRateLimit 组件的限流策略。这个组件不做多的介绍,想了解详情可以去访问官方网址或者原文地址,地址在文章底部,本文只讲实现。


.NET Core WebApi接口ip限流实践

前言

之前一直想实现接口限流,但一直没去实现,然后刚好看到一篇文章是基于AspNetCoreRateLimit 组件的限流策略。这个组件不做多的介绍,想了解详情可以去访问官方网址或者原文地址,地址在文章底部,本文只讲实现。

实现接口限流步骤

导包

.NET Core WebApi接口ip限流实践

第一步 配置服务

由于需要再appsettings.json中去读取数据,所以需要在Program.cs配置文件中配置服务

builder.Services.AddOptions(); 

第二步 写一个扩展方法注册RateLimit相关服务

using StackExchange.Redis; using AspNetCoreRateLimit; using AspNetCoreRateLimit.Redis;  namespace AspNetCoreRate {     public static class ConfigureRateLimit     {         public static void AddRateLimit(this IServiceCollection services,IConfiguration conf)         {             services.Configure<IpRateLimitOptions>(conf.GetSection("IpRateLimiting"));              // 注册 Redis 缓存服务             services.AddStackExchangeRedisCache(options =>             {                 options.Configuration = conf.GetConnectionString("Redis");             });             // 注册 Redis 连接服务             var redisOptions = ConfigurationOptions.Parse(conf.GetConnectionString("Redis"));             redisOptions.Password = "密码";             services.AddSingleton<IConnectionMultiplexer>(provider =>             {                 return ConnectionMultiplexer.Connect(redisOptions);             });             services.AddRedisRateLimiting();              services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();         }         public static IApplicationBuilder UseRateLimit(this IApplicationBuilder app)         {             app.UseIpRateLimiting();             return app;         }     } } 

第三步 注册服务

//注册服务 builder.Services.AddRateLimit(builder.Configuration); //将内存缓存服务注册到依赖注入容器中,可写可不写。 //builder.Services.AddDistributedMemoryCache(); 

builder.Services.AddDistributedMemoryCache();这个服务,看看chatGPT的回答

.NET Core WebApi接口ip限流实践

如果你不想使用内存缓存,也可以直接移除AddDistributedMemoryCache()服务的注册。在你的Startup.cs文件中,找到ConfigureServices方法,注释掉或者删除以下代码:

services.AddDistributedMemoryCache(); 

这样就可以移除内存缓存服务的注册了。不过,需要注意的是,如果你的Redis出现问题,应用程序将无法使用备用缓存,这可能会影响应用程序的性能和可用性。因此,建议你在使用Redis作为分布式缓存时,仍然注册AddDistributedMemoryCache()服务。?

第四步 添加中间件

//添加中间件 app.UseStaticFiles(new StaticFileOptions {     ServeUnknownFileTypes = true }); app.UseRateLimit(); 

记住把 UseRateLimit 放在 UseStaticFiles 后面,不然页面里的静态文件都被算进去访问次数,很快就被限流了。

第五步 在appsettings.json配置你的限流规则

  • EnableEndpointRateLimiting - 这个选项要设置为 true ,不然设置的限流是全局的,不能根据某个路径单独设置限流
  • StackBlockedRequests - 按照默认的设置为 false 就行,设置成 true 的话,一个接口被限流之后再重复请求还会计算到访问次数里面,这样有可能导致限流到天荒地老。
"IpRateLimiting": {     "EnableEndpointRateLimiting": true,     "StackBlockedRequests": false,     "RealIpHeader": "X-Real-IP",     "ClientIdHeader": "X-ClientId",     "HttpStatusCode": 429,     "IpWhitelist": [],     "GeneralRules": [       {       //被限流的接口访问地址,可设置多个         "Endpoint": "get:/api/GetUser",         //1分钟         "Period": "1m",         //限制次数 5次         "Limit": 5       }     ],     "QuotaExceededResponse": {       "Content": "{{ "message": "先别急,你访问得太快了!", "details": "已经触发限流。限流规则: 每 {1} 只能访问 {0} 次。请 {2} 秒后再重试。" }}",       "ContentType": "application/json",       "StatusCode": 429     }   },   "ConnectionStrings": {     "Redis": "redis服务器地址和端口号"   }, 
  • {0} - 规则。限制
  • {1} - 规则。时期
  • {2} - 重试后

实现效果

.NET Core WebApi接口ip限流实践

测试接口地址

演示效果接口地址

参考资料