首页 > 编程语言 >如何在 ASP.NET Core 中实现速率限制?

如何在 ASP.NET Core 中实现速率限制?

时间:2025-01-15 10:10:26浏览次数:1  
标签:Core ASP 限制 app maxRequests 中间件 速率 NET public

在 ASP.NET Core 中实现速率限制(Rate Limiting)中间件可以帮助你控制客户端对 API 的请求频率,防止滥用和过载。速率限制通常用于保护服务器资源,确保服务的稳定性和可用性。

ASP.NET Core 本身并没有内置的速率限制中间件,但你可以通过自定义中间件或使用第三方库来实现速率限制。以下是实现速率限制的几种常见方法:


1. 使用自定义中间件实现速率限制

你可以通过自定义中间件来实现速率限制。以下是一个简单的实现示例:

1.1 实现速率限制中间件

using Microsoft.AspNetCore.Http;
using System.Collections.Concurrent;
using System.Threading.Tasks;

public class RateLimitingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly int _maxRequests; // 每分钟允许的最大请求数
    private readonly ConcurrentDictionary<string, RateLimiter> _rateLimiters;

    public RateLimitingMiddleware(RequestDelegate next, int maxRequests)
    {
        _next = next;
        _maxRequests = maxRequests;
        _rateLimiters = new ConcurrentDictionary<string, RateLimiter>();
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 获取客户端的唯一标识(例如 IP 地址)
        var clientId = context.Connection.RemoteIpAddress.ToString();

        // 获取或创建速率限制器
        var rateLimiter = _rateLimiters.GetOrAdd(clientId, _ => new RateLimiter(_maxRequests));

        if (rateLimiter.AllowRequest())
        {
            await _next(context);
        }
        else
        {
            context.Response.StatusCode = StatusCodes.Status429TooManyRequests;
            await context.Response.WriteAsync("请求太多。请稍后再试.");
        }
    }
}

public class RateLimiter
{
    private readonly int _maxRequests;
    private int _requestCount;
    private DateTime _windowStart;

    public RateLimiter(int maxRequests)
    {
        _maxRequests = maxRequests;
        _requestCount = 0;
        _windowStart = DateTime.UtcNow;
    }

    public bool AllowRequest()
    {
        var now = DateTime.UtcNow;

        // 如果当前时间窗口已过期,重置计数器
        if ((now - _windowStart).TotalSeconds > 60)
        {
            _requestCount = 0;
            _windowStart = now;
        }

        // 检查请求是否超出限制
        if (_requestCount < _maxRequests)
        {
            _requestCount++;
            return true;
        }

        return false;
    }
}

1.2 注册中间件

Startup.cs 中注册中间件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseMiddleware<RateLimitingMiddleware>(10); // 每分钟最多 10个请求

    app.UseRouting();

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

2. 使用第三方库实现速率限制

如果你不想自己实现速率限制逻辑,可以使用一些现成的第三方库,例如:

2.1 AspNetCoreRateLimit

AspNetCoreRateLimit 是一个流行的 ASP.NET Core 速率限制库,支持 IP 地址、客户端 ID 和端点级别的速率限制。

安装

通过 NuGet 安装:

dotnet add package AspNetCoreRateLimit
配置

Startup.cs 中配置速率限制:

public void ConfigureServices(IServiceCollection services)
{
    // 添加内存缓存
    services.AddMemoryCache();

    // 配置速率限制
    services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
    services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
    services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
    services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
    services.AddSingleton<IProcessingStrategy, AsyncKeyLockProcessingStrategy>();
    services.AddInMemoryRateLimiting();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseIpRateLimiting();

    app.UseRouting();

    app.UseEndpoints(endpoints =>
                     {
                         endpoints.MapControllers();
                     });
}
配置文件

appsettings.json 中添加速率限制配置:

{
    "IpRateLimiting": {
        "EnableEndpointRateLimiting": true,
        "StackBlockedRequests": false,
        "RealIpHeader": "X-Real-IP",
        "ClientIdHeader": "X-ClientId",
        "GeneralRules": [
            {
                "Endpoint": "*",
                "Period": "1m",
                "Limit": 10
                }
        ]
    }
}

3. 使用分布式缓存实现速率限制

如果你的应用是分布式的(例如部署在 Kubernetes 或多个服务器上),可以使用分布式缓存(如 Redis)来实现速率限制。

3.1 使用 Redis 实现速率限制

你可以使用 Redis 来存储每个客户端的请求计数。以下是一个简单的示例:

using Microsoft.AspNetCore.Http;
using StackExchange.Redis;
using System.Threading.Tasks;

public class RedisRateLimitingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly int _maxRequests;
    private readonly ConnectionMultiplexer _redis;

    public RedisRateLimitingMiddleware(RequestDelegate next, int maxRequests, ConnectionMultiplexer redis)
    {
        _next = next;
        _maxRequests = maxRequests;
        _redis = redis;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var clientId = context.Connection.RemoteIpAddress.ToString();
        var db = _redis.GetDatabase();

        var key = $"rate_limit:{clientId}";
        var requestCount = await db.StringIncrementAsync(key);

        if (requestCount == 1)
        {
            await db.KeyExpireAsync(key, TimeSpan.FromMinutes(1));
        }

        if (requestCount > _maxRequests)
        {
            context.Response.StatusCode = StatusCodes.Status429TooManyRequests;
            await context.Response.WriteAsync("请求太多。请稍后再试.");
        }
        else
        {
            await _next(context);
        }
    }
}

3.2 注册中间件

Startup.cs 中注册中间件:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ConnectionMultiplexer>(ConnectionMultiplexer.Connect("localhost:6379"));
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseMiddleware<RedisRateLimitingMiddleware>(10); // 每分钟最多 10个请求

    app.UseRouting();

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

4. 总结

在 ASP.NET Core 中实现速率限制有多种方式:

  • 自定义中间件:适合简单的场景,但需要自己实现逻辑。
  • 第三方库:如 AspNetCoreRateLimit,提供了更强大的功能和灵活性。
  • 分布式缓存:如 Redis,适合分布式环境。

根据你的需求选择合适的方式,确保你的 API 能够有效防止滥用和过载。

标签:Core,ASP,限制,app,maxRequests,中间件,速率,NET,public
From: https://www.cnblogs.com/liyongqiang-cc/p/18628407

相关文章

  • PoE(Power over Ethernet)
    PoE(PoweroverEthernet)是一种通过网线同时传输电力和数据的技术。它允许网络设备(如IP电话、无线接入点、IP摄像头等)通过以太网电缆获取电力,而无需单独的电源线12。PoE有几个标准:IEEE802.3af:也称为标准PoE,提供最高15.4W的电力。IEEE802.3at:也称为PoE+,提供最高25.5W的电力。I......
  • .NET 数据拷贝方案选择
     应用中我们经常使用到数据的复制,在.NET中有多种方式可以实现复制数据或对象。选择哪种方式、是浅拷贝还是深拷贝,具体需求场景可以取决于对象的复杂性、数据量等,本文我们介绍主要的拷贝方式以及相对高性能的方案。 1.MemberwiseClone拷贝浅拷贝 Object.MemberwiseClone方法......
  • C#/.NET/.NET Core技术前沿周刊 | 第 21 期(2025年1.6-1.12)
    前言C#/.NET/.NETCore技术前沿周刊,你的每周技术指南针!记录、追踪C#/.NET/.NETCore领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿,助力技术成长与视野拓宽。欢迎投稿、推荐或自荐优质文章、项目、学习资源等。......
  • ASP.NET Core 中的高效后台任务管理
    一、引言在当今快速发展的Web开发领域,ASP.NETCore凭借其卓越的性能、强大的功能和高度的灵活性,已然成为众多开发者构建现代Web应用程序的首选框架。它不仅能够高效地处理各种复杂的业务逻辑,还为开发者提供了丰富多样的工具和功能,以满足不同项目的需求。在众多功能中......
  • 构建高性能网络服务:从 Socket 原理到 Netty 应用实践
    1.引言在Java网络编程中,Socket是实现网络通信的基础(可以查看我的上一篇博客)。它封装了TCP/IP协议栈,提供了底层通信的核心能力。而Netty是在Socket和NIO的基础上,进一步封装的高性能、异步事件驱动的网络框架,简化了复杂的网络编程。为什么需要学习Socket?学习......
  • 网络安全必备 | Metasploit工具实操全攻略
    免责声明:该文章所涉及到的安全工具和技术仅做分享和技术交流学习使用,使用时应当遵守国家法律,做一位合格的白帽专家。使用本工具的用户需要自行承担任何风险和不确定因素,如有人利用工具做任何后果均由使用者承担,本人及文章作者还有泷羽sec团队不承担任何责任B站红队公益课......
  • 【转】.net 下SSE使用demo
    转自:https://www.cnblogs.com/SmallChen/p/15080231.html所谓SSE,就是浏览器向服务器发送一个HTTP请求,然后服务器不断单向地向浏览器推送“信息”(message)。这种信息在格式上很简单,就是“信息”加上前缀“data:”,然后以“\n\n”结尾(既是所谓的事件流:通过一个持久的HTTP响应发送,这......
  • 在eNSp上telnet一下吧
    在上篇博客:DNS 我们提到了telnet和设备带外管理、带内管理,它确实是非常有趣的一个知识点哦,接下来我们一起来学习学习吧~ Telnet(远程登陆协议)Telnet基于TCP23号端口,典型的C/S架构模式,是一种用于远程登录到计算机和通过网络进行通信的协议。它允许用户从本地计算机上通过网......
  • 用于决策的世界模型 -- 论文 World Models (2018) & PlaNet (2019) 讲解
    参考资料:[2411.14499]UnderstandingWorldorPredictingFuture?AComprehensiveSurveyofWorldModels[1803.10122]WorldModelsLearningLatentDynamicsforPlanningfromPixelsKaixhin/PlaNet:DeepPlanningNetwork:Controlfrompixelsbylatentplanning......
  • 推荐一款 .NET 智慧水务物联网系统
    前言本文将介绍如何通过智能水表(如NB-IoT水表)、智能消火栓、智能阀门、数据采集终端(RTU或PLC)及其他前置传感器和设备,开发一个高效、智能的供水管理系统。该系统能够实时采集和分析供水网络中的各种数据,帮助用户单位实现精细化管理和资源优化配置。项目介绍智慧水务物联网系......