C#如何实现Rate Limiting ASP.NET Core速率限制中间件用法

来源:这里教程网 时间:2026-02-21 17:40:15 作者:

ASP.NET Core 中实现速率限制(Rate Limiting)推荐使用官方内置的

Microsoft.AspNetCore.RateLimiting
包(.NET 7+ 原生支持),它比第三方库更轻量、更集成、更易配置。

启用 Rate Limiting 中间件

Program.cs
中注册并启用中间件:

调用
AddRateLimiter()
添加服务,可配置多种策略
调用
UseRateLimiter()
启用中间件(必须放在
UseAuthorization()
之后、
UseEndpoints()
之前)

示例:

// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRateLimiter(options =>
{
    options.AddFixedWindowLimiter("fixed", opt =>
    {
        opt.Window = TimeSpan.FromSeconds(60);
        opt.PermitLimit = 10;
        opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
        opt.QueueLimit = 5;
    });
});
// ... 其他服务注册
var app = builder.Build();
app.UseRateLimiter(); // ⚠️ 位置很重要
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();

为控制器或方法应用限流策略

使用

[EnableRateLimiting("policy-name")]
特性标记端点:

可加在 Controller 类上(全局生效),也可加在单个 Action 方法上(更精细) 策略名必须与
AddRateLimiter
中注册的名称一致
未标记的端点默认不受限

示例:

[ApiController]
[Route("api/[controller]")]
[EnableRateLimiting("fixed")] // 整个控制器启用
public class ValuesController : ControllerBase
{
    [HttpGet]
    public IActionResult Get() => Ok(new[] { "a", "b" });
    [HttpPost]
    [DisableRateLimiting] // 可对个别方法禁用
    public IActionResult Post() => Ok();
}

支持的限流算法及配置要点

内置策略包括 Fixed Window、Sliding Window、Token Bucket,常用的是前两种:

Fixed Window:简单高效,但存在窗口边界突增问题(如每分钟10次,0:59和1:00各来10次 → 实际20次) Sliding Window:更精准(如每60秒最多10次),适合高一致性要求场景,但需存储支持(如 Redis) 策略可指定
KeyGenerator
自定义限流键,例如按 IP、用户 ID 或请求头区分

Sliding Window 示例:

options.AddSlidingWindowLimiter("sliding", opt =>
{
    opt.Window = TimeSpan.FromMinutes(1);
    opt.SegmentsPerWindow = 12; // 拆成12段(每5秒一段)
    opt.PermitLimit = 10;
    opt.QueueLimit = 3;
});

自定义限流键(按用户/IP/租户区分)

默认按客户端 IP 限流,可通过

KeyGenerator
改为按用户身份、请求头等维度:

返回字符串作为唯一键,相同键共享配额 例如:登录用户用
HttpContext.User.FindFirst(ClaimTypes.NameIdentifier)?.Value
注意空值处理,避免 null 引发异常

示例(按用户 ID):

options.AddFixedWindowLimiter("per-user", opt =>
{
    opt.Window = TimeSpan.FromMinutes(1);
    opt.PermitLimit = 5;
    opt.KeyGenerator = async context =>
    {
        var userId = context.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? "anonymous";
        return userId;
    };
});

基本上就这些。官方 Rate Limiting 中间件开箱即用,无需额外存储(Fixed Window 内存即可),配合策略配置和特性标注,就能快速落地生产级限流能力。

相关推荐