Erweiterte API-Resilienz mit Refit, Polly, Refitter, Rate Limiting und Circuit Breaker

Nachdem wir die grundlegende Integration von Refit, Polly und Refitter in API-Projekte besprochen haben, wollen wir nun einen Schritt weiter gehen und uns mit fortgeschrittenen Resilienzmechanismen befassen. Besonders im Kontext von APIs, die häufige Anfragen stellen, ist es wichtig, sicherzustellen, dass die Anwendung Anfrageraten kontrolliert und bei Erreichen von Grenzen angemessen reagiert. Hier kommen das Rate Limiting, die AsyncRateLimitPolicy und der Circuit Breaker ins Spiel.

1. Rate Limiting: Anfragen pro Sekunde beschränken

Rate Limiting ist eine wichtige Strategie, um sicherzustellen, dass eine Anwendung API-Server nicht überlastet. Eine gängige Anforderung ist es, die Anzahl der API-Anfragen auf einen bestimmten Wert pro Sekunde zu begrenzen.

Polly bietet hierfür die AsyncRateLimitPolicy, mit der Sie die Anzahl der Anfragen pro Zeiteinheit begrenzen können. Dies ist besonders nützlich, wenn die API, die Sie konsumieren, eigene Ratenlimits durchsetzt.

Beispiel:

var rateLimitPolicy = Policy.RateLimitAsync(60, TimeSpan.FromSeconds(1));

services.AddRefitClient<IMyApi>()
    .ConfigureHttpClient(c => c.BaseAddress = new Uri("https://api.example.com"))
    .AddPolicyHandler(rateLimitPolicy)
    .AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(600)));

In diesem Beispiel erlaubt das RateLimitPolicy, dass maximal 60 Anfragen pro Sekunde gestellt werden. Wenn dieses Limit überschritten wird, wird eine RateLimitRejectedException ausgelöst, die entweder behandelt oder verzögert werden kann.

2. Circuit Breaker: Verhindern von Überlastungen

Der Circuit Breaker ist ein weiterer Resilienzmechanismus, der dazu dient, eine API vor Überlastungen zu schützen, indem er fehlerhafte Anfragen frühzeitig unterbricht. Der Circuit Breaker wird aktiviert, wenn eine bestimmte Anzahl von Fehlern innerhalb eines bestimmten Zeitraums auftritt, und verhindert weitere Anfragen, bis die API sich wieder stabilisiert hat.

Beispiel mit Circuit Breaker:

var circuitBreakerPolicy = Policy.Handle<HttpRequestException>()
    .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1));

services.AddRefitClient<IMyApi>()
    .ConfigureHttpClient(c => c.BaseAddress = new Uri("https://api.example.com"))
    .AddPolicyHandler(rateLimitPolicy)
    .AddPolicyHandler(circuitBreakerPolicy)
    .AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(600)));

In diesem Beispiel wird der Circuit Breaker nach zwei aufeinanderfolgenden Fehlern aktiviert und blockiert weitere Anfragen für eine Minute. Dies gibt der API Zeit, sich zu erholen, und verhindert, dass eine fehlerhafte API weiter überlastet wird.

3. Kombination von Rate Limiting und Circuit Breaker

Die Kombination aus Rate Limiting und Circuit Breaker sorgt für eine robuste API-Integration, die sowohl gegen Überlastung als auch gegen Ausfälle geschützt ist. Durch das Einrichten von Ratenlimits wird sichergestellt, dass API-Server nicht durch zu viele Anfragen überlastet werden. Gleichzeitig schützt der Circuit Breaker die Anwendung vor wiederholten Fehlern, indem er nach einem bestimmten Schwellenwert eingreift.

Erweitertes Beispiel:

public void ConfigureServices(IServiceCollection services)
{
    var rateLimitPolicy = Policy.RateLimitAsync(60, TimeSpan.FromSeconds(1));
    var circuitBreakerPolicy = Policy.Handle<HttpRequestException>()
        .CircuitBreakerAsync(2, TimeSpan.FromMinutes(1));
    
    services.AddRefitClient<IMyApi>()
        .ConfigureHttpClient(c => c.BaseAddress = new Uri("https://api.example.com"))
        .AddPolicyHandler(rateLimitPolicy)
        .AddPolicyHandler(circuitBreakerPolicy)
        .AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(10)))
        .AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(600)));
}

In diesem erweiterten Beispiel werden alle drei Mechanismen kombiniert, um eine API-Integration zu schaffen, die nicht nur effizient, sondern auch äußerst widerstandsfähig ist. Diese Konfiguration ist besonders nützlich in Produktionsumgebungen, in denen hohe Stabilität und Zuverlässigkeit erforderlich sind.

4. Fazit

Die Implementierung von Rate Limiting und Circuit Breaker in Kombination mit Refit, Polly und Refitter bietet eine umfassende Lösung für die API-Integration in .NET-Projekten. Diese Tools sorgen dafür, dass Ihre Anwendung Anfragen effektiv verwaltet, API-Server vor Überlastung schützt und dennoch flexibel und robust genug ist, um auch unter schwierigen Bedingungen stabil zu bleiben.

Durch den Einsatz dieser fortgeschrittenen Resilienzstrategien können Sie sicherstellen, dass Ihre Anwendung nicht nur effizient, sondern auch nachhaltig und skalierbar ist.

Print Friendly, PDF & Email