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

实现效果

参考资料

相关推荐
希望永不加班39 分钟前
Spring AOP 代理模式:CGLIB 与 JDK 动态代理区别
java·开发语言·后端·spring·代理模式
浮游本尊2 小时前
一次合同同步背后的多阶段流水线:从外部主数据到本地歧义消解
后端
lv__pf2 小时前
springboot原理
java·spring boot·后端
段小二2 小时前
服务一重启全丢了——Spring AI Alibaba Agent 三层持久化完整方案
java·后端
UIUV3 小时前
Go语言入门到精通学习笔记
后端·go·编程语言
lizhongxuan3 小时前
开发 Agent 的坑
后端
段小二3 小时前
Agent 自动把机票改错了,推理完全正确——这才是真正的风险
java·后端
itjinyin3 小时前
ShardingSphere-jdbc 5.5.0 + spring boot 基础配置 - 实战篇
java·spring boot·后端
Victor3563 小时前
MongoDB(91)如何在MongoDB中使用TTL索引?
后端