Blog Dla Programistów C#/.NET

środa, 26 listopada 2025

Wyobraź sobie, że twój program musi wysyłać zapytania do zewnętrznego API pogodowego, które pozwala na maksymalnie 100 żądań na godzinę. Co się stanie, jeśli spróbujesz wysłać 200 żądań w ciągu minuty? Najprawdopodobniej część z nich zostanie odrzucona albo otrzymasz błąd HTTP 429 Too Many Requests – sygnał, że przekroczyłeś dopuszczalny limit. Aby unikać takich sytuacji i chronić zarówno zewnętrzne API, jak i własne aplikacje przed przeciążeniem, stosujemy mechanizm rate limiting. Mówiąc prościej, rate limiting to ograniczanie liczby operacji (np. wywołań API) wykonywanych w określonym czasie, tak aby nie przekroczyć ustalonego limitu. Dzięki temu możemy zadbać o stabilność usług i sprawiedliwe wykorzystanie zasobów.

Limit Prędkości Dla API - Czyli Rate Limiting w C#

Dlaczego warto ograniczać tempo żądań?


Mechanizmy rate limiting przydają się w wielu scenariuszach – od bezpieczeństwa po wydajność. Oto kilka głównych powodów, dla których warto kontrolować tempo żądań w aplikacji:
    
Ochrona przed przeciążeniem: Limitowanie zapytań zapobiega zalewaniu serwera zbyt dużą liczbą żądań naraz (np. przez błąd w pętli lub atak typu DDoS). Dzięki temu Twoja aplikacja pozostaje responsywna.
    
Przestrzeganie limitów zewnętrznych API: Wiele usług (np. API Google, Twittera) narzuca własne limity na liczbę wywołań w danym przedziale czasu. Stosując rate limiting po stronie klienta, unikniesz blokady lub błędów wynikających z przekroczenia tych limitów.
    
Sprawiedliwe użycie zasobów: Jeśli z Twojego API korzysta wielu użytkowników, ograniczenie liczby żądań na użytkownika zapobiega sytuacji, w której jeden klient zużywa większość zasobów kosztem innych. Każdy dostaje swoją "działkę" w ustalonym tempie.


Implementacja Rate Limiting w C#


Skoro wiemy, po co nam ograniczanie tempa, zobaczmy jak zaimplementować rate limiting w C#. Mamy kilka podejść – od własnoręcznych rozwiązań po gotowe biblioteki. Poniżej opisuję najpopularniejsze metody:
    
Własna implementacja w kodzie: Możesz samodzielnie napisać logikę ograniczającą wywołania. Najprostszy sposób to zliczanie operacji w ustalonym okienku czasowym. Na przykład, możesz założyć, że pozwalasz na 5 wywołań na sekundę – tworzysz licznik wywołań i co sekundę go zerujesz. Gdy licznik przekroczy 5 przed upływem sekundy, kolejne żądania muszą poczekać (lub zostać pominięte). To podejście daje pełną kontrolę, ale wymaga zadbania o wątki (gdy wiele wywołań dzieje się równocześnie) i ręcznego dostosowania algorytmu (np. stałe okno vs. okno przesuwne). Poniżej prosty przykład takiej implementacji fixed window:

int maxCalls = 5;
TimeSpan window = TimeSpan.FromSeconds(1);
int callCount = 0;
DateTime windowStart = DateTime.UtcNow;

void AttemptAction()
{
var now = DateTime.UtcNow;
if (now - windowStart > window)
{
/* Nowe okno czasowe – zresetuj licznik */
callCount = 0;
windowStart = now;
}

if (callCount < maxCalls)
{
callCount++;
/* Tutaj wykonaj właściwą akcję, np. wywołanie API */
Console.WriteLine("Akcja wykonana.");
}
else
{
Console.WriteLine("Zbyt wiele żądań! Poczekaj chwilę.");
/* Ewentualnie: Thread.Sleep(window - (now - windowStart)); */
}
}

• Biblioteka Polly (rate limiting po stronie klienta): Zamiast pisać wszystko samemu, możesz skorzystać z gotowych bibliotek. Jedną z popularnych jest Polly – biblioteka do tworzenia polityk odporności (resilience), która obsługuje m.in. retry, circuit breaker, a także rate limit. Za pomocą Polly możesz ustawić politykę, która pozwoli na określoną liczbę wywołań na sekundę. Gdy limit zostanie przekroczony, Polly rzuci wyjątek lub opóźni kolejne wywołanie – dzięki czemu Twoja aplikacja kliencka nie zbombarduje zewnętrznego serwisu nadmiarem żądań. To wygodne rozwiązanie np. gdy Twój kod wykonuje wiele żądań HTTP i chcesz ograniczyć ich częstotliwość. W praktyce użycie Polly sprowadza się do zdefiniowania polityki (np. Policy.RateLimit) i owrapowania nią wywołań HTTP – biblioteka zajmie się resztą.
    
Wbudowane middleware w ASP.NET Core (od .NET 7 wzwyż): Jeśli tworzysz web API w ASP.NET Core, framework udostępnia gotowy mechanizm rate limiting jako middleware. Wystarczy dodać odpowiedni pakiet (np. Microsoft.AspNetCore.RateLimiting) i skonfigurować polityki limitów w kodzie startowym aplikacji. Możesz definiować limity globalne lub per endpoint – np. ograniczyć dany adres URL do 10 żądań na minutę dla jednego użytkownika. .NET 7 i .NET 8 oferują kilka algorytmów do wyboru (takich jak fixed window, sliding window, token bucket czy concurrency limit). Przykładowo, aby zastosować prosty fixed window w API, konfigurujesz w Program.cs coś takiego:

builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("myPolicy", opt =>
{
opt.Window = TimeSpan.FromMinutes(1);
opt.PermitLimit = 10; /* maks 10 żądań na okno (minutę) */
opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
opt.QueueLimit = 0; /* brak kolejkowania nadmiarowych żądań */
});
});
app.UseRateLimiter();
app.MapGet("/moje-api", HandleRequest).RequireRateLimiting("myPolicy");

Powyższa konfiguracja oznacza: dla endpointu /moje-api zezwalaj maksymalnie na 10 wywołań na minutę. Nadmiarowe żądania zostaną odrzucone automatycznie z kodem HTTP 429. Co ważne, gotowe middleware obsługuje też bardziej zaawansowane scenariusze (np. sliding window, które lepiej radzi sobie z nagłymi burstami żądań, czy token bucket, który dozująco dodaje "tokeny" w czasie). Dzięki temu nie musisz samodzielnie kodować tych algorytmów – wystarczy skonfigurować odpowiednią politykę.


Podsumowanie


Rate limiting to przydatna technika, która pomaga utrzymać nasze aplikacje w ryzach – zapobiega przeciążeniom i pozwala dotrzymywać narzuconych limitów. W C# i .NET możemy zaimplementować ją na różne sposoby: od prostych liczników w kodzie, po użycie dojrzałych narzędzi jak Polly czy wbudowane funkcje platformy. Ważne jest, by świadomie korzystać z tych mechanizmów tam, gdzie są potrzebne (np. przy integracjach z API zewnętrznymi lub w celu ochrony własnego serwisu). Dzięki temu nasze aplikacje działają stabilnie i przewidywalnie, a my śpimy spokojniej wiedząc, że nie grozi nam nagłe przekroczenie limitów.

Na koniec warto dodać, że nauka takich praktycznych zagadnień to świetny krok w rozwoju każdego początkującego programisty. Jeśli chcesz systematycznie opanować podobne tematy i pewnie wejść w świat C#/.NET, zachęcam do sprawdzenia mojego kursu online "Zostań Programistą .NET" – to kompletny program szkoleniowy, który prowadzi od podstaw aż do pierwszej pracy jako młodszy developer.

Autor artykułu:
Kazimierz Szpin
Kazimierz Szpin
CTO & Founder - FindSolution.pl
Programista C#/.NET. Specjalizuje się w Blazor, ASP.NET Core, ASP.NET MVC, ASP.NET Web API, WPF oraz Windows Forms.
Autor bloga ModestProgrammer.pl
Dodaj komentarz

Wyszukiwarka

© Copyright 2025 modestprogrammer.pl | Sztuczna Inteligencja | Regulamin | Polityka prywatności. Design by Kazimierz Szpin. Wszelkie prawa zastrzeżone.