返回首页

ASP.NET Core 限流:设置和算法

在 ASP.NET Core 中设置限流的指南。描述算法(Fixed Window、Token Bucket)、策略、队列和拒绝处理。项目集成的代码示例。

ASP.NET Core 中的限流:算法和策略
Advertisement 728x90

# 在 ASP.NET Core 中设置速率限制:开发者分步指南

ASP.NET Core 中的速率限制功能可以帮助您控制服务器负载、防范 DoS 攻击,并确保资源公平分配。设置只需两个步骤:注册服务并将中间件添加到管道中。所有依赖项均包含在 SDK 中,无需额外包。

在 Program.cs 中,在 WebApplicationBuilder.Services 上调用 AddRateLimiter

builder.Services.AddRateLimiter(options =>
{
    // Konfiguratsiya politik
});

然后添加中间件:

Google AdInline article slot
app.UseRateLimiter();

这是基本集成。接下来介绍算法和策略的详细内容。

算法与选择性限制

ASP.NET Core 支持多种速率限制算法:

  • Fixed Window — 固定时间窗口,简单但容易出现负载峰值。
  • Sliding Window — 滑动窗口,更均匀地分配限制。
  • Token Bucket — 令牌桶,允许突发流量。
  • Concurrency Limiter — 限制并发请求。

选择性决定了限制哪些请求。全局限制器适用于所有请求,而选择性限制器则使用键(IP、用户 ID)。

Google AdInline article slot

全局限制器示例(每分钟 100 个请求):

options.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, string>(
    httpContext => RateLimitPartition.GetFixedWindowLimiter(
        partitionKey: httpContext.Request.Headers.Host.ToString(),
        factory: partition => new FixedWindowRateLimiterOptions
        {
            AutoReplenishment = true,
            PermitLimit = 100,
            Window = TimeSpan.FromMinutes(1)
        }));
);

分组与组合限制器

按键分组是选择性的基础。使用 AddFixedWindowLimiter 或自定义策略。

键分组场景:

Google AdInline article slot
  • 按 IP:partitionKey: httpContext.Connection.RemoteIpAddress?.ToString()
  • 按客户端:partitionKey: httpContext.User.Identity?.Name
  • 按 API 端点:partitionKey: httpContext.Request.Path
  • 组合键:IP + User-Agent

通过 AddPolicy 组合选择性限制器:

options.AddPolicy("ip", httpContext =>
{
    var ip = httpContext.Connection.RemoteIpAddress;
    return new FixedWindowRateLimiterOptions
    {
        PermitLimit = 50,
        Window = TimeSpan.FromMinutes(1),
        QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
        QueueLimit = 10
    };
});

新功能:组合非选择性限制器——带队列的多个全局限制器。

队列与拒绝处理

启用队列以平滑峰值:

  • QueueLimit — 队列最大长度。
  • QueueProcessingOrder — 处理顺序(OldestFirst / NewestFirst)。

拒绝操作可以全局设置或按策略设置:

options.OnRejected = (context, token) =>
{
    context.HttpContext.Response.StatusCode = 429;
    context.HttpContext.Response.ContentType = "application/json";
    return context.HttpContext.Response.WriteAsync(
        "{"too many requests. try again later.", token);
};

命名和匿名策略

命名策略 通过特性应用于控制器/操作:

[EnableRateLimiting("policy1")]
public class ApiController : ControllerBase { }

简单注册:

options.AddPolicy("policy1", httpContext =>
    new TokenBucketRateLimiterOptions
    {
        TokenLimit = 100,
        QueueLimit = 20,
        ReplenishmentPeriod = TimeSpan.FromMinutes(1),
        TokensPerPeriod = 100,
        AutoReplenishment = true
    });

匿名策略 —— MS 文档未涵盖的额外功能。通过 IRateLimiter 直接在选择器中实现。

示例:

options.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext>(
    context => new CustomRateLimiter(context));

public class CustomRateLimiter : FixedWindowRateLimiter
{
    // Kastomnaya logic
}

链接到路由:[EnableRateLimiting("api")] 或使用 [DisableRateLimiting] 禁用。

要点

  • 速率限制在中件件层面运行,在控制器之前。
  • 始终为 429 Too Many Requests 配置 OnRejected
  • 在高负载场景中使用队列。
  • 组合策略以实现细粒度控制(IP + 端点)。
  • 匿名策略扩展了标准 API 之外的能力。

— Editorial Team

Advertisement 728x90

继续阅读