Zpět na domů

Rate limiting ASP.NET Core: nastavení a algoritmy

Průvodce nastavením rate limiting v ASP.NET Core. Popsány algoritmy (Fixed Window, Token Bucket), politiky, fronty a zpracování odmítnutí. Příklady kódu pro integraci do projektů.

Rate Limiting v ASP.NET Core: algoritmy a politiky
Advertisement 728x90

Nastavení rate limiting v ASP.NET Core: podrobný návod pro vývojáře

Funkce omezení rychlosti požadavků (rate limiting) v ASP.NET Core umožňuje kontrolovat zátěž serveru, chránit před DoS útoky a zajišťovat spravedlivé rozdělení zdrojů. Nastavení vyžaduje dva kroky: registraci služeb a přidání middleware do pipeline. Všechny závislosti jsou zahrnuty v SDK bez dalších balíčků.

V Program.cs zavolejte AddRateLimiter na WebApplicationBuilder.Services:

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

Poté přidejte middleware:

Google AdInline article slot
app.UseRateLimiter();

Toto je základní integrace. Dále následuje podrobnost o algoritmech a politikách.

Algoritmy a selektivita omezení

ASP.NET Core podporuje několik algoritmů rate limiting:

  • Fixed Window — pevné časové okno, jednoduché, ale s špičkami zátěže.
  • Sliding Window — posunuté okno, rovnoměrněji rozkládá limity.
  • Token Bucket — kbelík s tokeny, umožňuje burst-traffic.
  • Concurrency Limiter — omezení podle paralelních požadavků.

Selektivita určuje, které požadavky omezovat. Globální limitér se aplikuje na všechny, selektivní podle klíčů (IP, user ID).

Google AdInline article slot

Příklad globálního limitéru (100 požadavků za minutu):

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)
        })));

Seskupování a kombinování limitérů

Seskupování podle klíče je základem selektivity. Používejte AddFixedWindowLimiter nebo vlastní politiky.

Označený seznam klíčových scénářů seskupování:

Google AdInline article slot
  • Podle IP: partitionKey: httpContext.Connection.RemoteIpAddress?.ToString()
  • Podle klienta: partitionKey: httpContext.User.Identity?.Name
  • Podle API endpointu: partitionKey: httpContext.Request.Path
  • Kombinovaný klíč: IP + User-Agent

Kombinování selektivních limitérů prostřednictvím AddPolicy:

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

Nová možnost — kombinování neselektivních: několik globálních limitérů s frontami.

Fronty a zpracování odmítnutí

Zapněte fronty pro vyhlazení špiček:

  • QueueLimit — maximum ve frontě.
  • QueueProcessingOrder — pořadí (OldestFirst / NewestFirst).

Akce při odmítnutí se nastavují globálně nebo per-policy:

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);
};

Pojmenované a nepojmenované politiky

Pojmenované politiky se aplikují atributy na controllery/akce:

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

Jednoduchá registrace:

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

Nepojmenované politiky — bonus, který není popsán v dokumentaci MS. Realizují se přímo přes IRateLimiter v selektorech.

Příklad:

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

public class CustomRateLimiter : FixedWindowRateLimiter
{
    // Vlastní logika
}

Propojení s routy: [EnableRateLimiting("api")] nebo vypnutí [DisableRateLimiting].

Co je důležité

  • Rate limiting funguje na úrovni middleware, před controllery.
  • Vždy nastavte OnRejected pro 429 Too Many Requests.
  • Používejte fronty pro high-load scénáře.
  • Kombinujte politiky pro granulární kontrolu (IP + endpoint).
  • Nepojmenované politiky rozšiřují možnosti za hranice standardního API.

— Editorial Team

Advertisement 728x90

Číst dál