.NET Core WebApi接口ip限流实践

.NET Core WebApi接口ip限流实践

前言

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

实现接口限流步骤

导包

第一步 配置服务

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

ini 复制代码
builder.Services.AddOptions();

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

c# 复制代码
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;
        }
    }
}

第三步 注册服务

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

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

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

csharp 复制代码
services.AddDistributedMemoryCache();

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

第四步 添加中间件

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

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

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

  • EnableEndpointRateLimiting - 这个选项要设置为 true ,不然设置的限流是全局的,不能根据某个路径单独设置限流
  • StackBlockedRequests - 按照默认的设置为 false 就行,设置成 true 的话,一个接口被限流之后再重复请求还会计算到访问次数里面,这样有可能导致限流到天荒地老。
swift 复制代码
"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} - 重试后

实现效果

参考资料

相关推荐
酷爱码38 分钟前
springboot 动态配置定时任务
java·spring boot·后端
计算机-秋大田1 小时前
基于SpringBoot的美食烹饪互动平台的设计与实现(源码+SQL脚本+LW+部署讲解等)
vue.js·spring boot·后端·课程设计·美食
加油,旭杏1 小时前
【go语言】grpc 快速入门
开发语言·后端·golang
brzhang1 小时前
墙裂推荐一个在 Apple Silicon 上创建和管理虚拟机的轻量级开源工具:lume
前端·后端
沈韶珺3 小时前
Visual Basic语言的云计算
开发语言·后端·golang
沈韶珺3 小时前
Perl语言的函数实现
开发语言·后端·golang
美味小鱼3 小时前
Rust 所有权特性详解
开发语言·后端·rust
我的K84093 小时前
Spring Boot基本项目结构
java·spring boot·后端
慕璃嫣4 小时前
Haskell语言的多线程编程
开发语言·后端·golang
晴空๓4 小时前
Spring Boot项目如何使用MyBatis实现分页查询
spring boot·后端·mybatis