.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} - 重试后

实现效果

参考资料

相关推荐
码农派大星。3 分钟前
Spring Boot 配置文件
java·spring boot·后端
杜杜的man43 分钟前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*44 分钟前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
llllinuuu1 小时前
Go语言结构体、方法与接口
开发语言·后端·golang
cookies_s_s1 小时前
Golang--协程和管道
开发语言·后端·golang
为什么这亚子1 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
想进大厂的小王1 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构
customer082 小时前
【开源免费】基于SpringBoot+Vue.JS医院管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·开源·intellij-idea
2402_857589362 小时前
SpringBoot框架:作业管理技术新解
java·spring boot·后端
一只爱打拳的程序猿2 小时前
【Spring】更加简单的将对象存入Spring中并使用
java·后端·spring