Was ist Polly und warum wird es benötigt?
Polly ist eine leistungsstarke und flexible Bibliothek für .NET (C#, F#, VB.NET), die zur Behandlung temporärer Ausfälle und zur Erhöhung der Ausfallsicherheit von Anwendungen entwickelt wurde. Sie implementiert bewährte Resilienz-Muster wie Wiederholungsversuche (Retry), Unterbrechung (Circuit Breaker), Timeouts, Isolation (Bulkhead Isolation) und Caching.
In der heutigen Welt der Microservices und Cloud-Computing interagieren Anwendungen ständig mit externen Ressourcen: Datenbanken, Webdiensten und APIs. Diese Interaktionen können unzuverlässig sein – Netzwerkfehler, vorübergehende Nichtverfügbarkeit eines Dienstes oder Überschreitung von Anfragelimitierungen. Polly ermöglicht es, solche Situationen elegant zu handhaben, ohne umständlichen Code mit try-catch-Blöcken schreiben zu müssen.
Die wichtigsten Einsatzszenarien:
- Retry (Wiederholungsversuche): Automatisches Wiederholen eines Vorgangs bei einem temporären Fehler.
- Circuit Breaker (Unterbrechung): Aussetzen von Aufrufversuchen, wenn ein Dienst dauerhaft Fehler liefert, um ihm Zeit zur Erholung zu geben.
- Timeout (Zeitüberschreitung): Begrenzung der Ausführungszeit eines Vorgangs.
- Bulkhead (Isolation): Begrenzung der Anzahl paralleler Vorgänge, damit ein einzelner "schlechter" Vorgang nicht den gesamten Thread-Pool blockiert.
- Cache (Zwischenspeicherung): Zwischenspeichern von Ergebnissen erfolgreicher Vorgänge.
- Fallback (Ausweichlösung): Ausführen einer alternativen Aktion im Fehlerfall.
Installation von Polly
Polly wird über NuGet, den Paketmanager für .NET, vertrieben. Die Installation kann auf verschiedene Weisen erfolgen:
Über die Package Manager Console (Visual Studio)
Install-Package Polly
Über die .NET CLI
dotnet add package Polly
Über PackageReference (in der .csproj-Datei)
<PackageReference Include="Polly" Version="8.2.0" />
Fügen Sie nach der Installation die entsprechenden using-Direktiven in Ihren Code ein:
using Polly;
using Polly.Retry;
using Polly.CircuitBreaker;
using Polly.Timeout;
using Polly.Bulkhead;
using Polly.Caching;
using Polly.Fallback;
using Polly.Wrap;
Schnellstart mit einem Codebeispiel
Betrachten wir ein einfaches Beispiel: Wir haben eine Methode, die eine externe API aufruft, und möchten den Aufruf bei Auftreten einer Ausnahme 3 Mal wiederholen.
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Polly;
using Polly.Retry;
public class ApiClient
{
private readonly HttpClient _httpClient;
private readonly AsyncRetryPolicy _retryPolicy;
public ApiClient()
{
_httpClient = new HttpClient();
// Erstellen der Wiederholungsrichtlinie
_retryPolicy = Policy
.Handle<HttpRequestException>() // Welche Ausnahmen behandelt werden
.Or<TimeoutException>() // Oder Timeout
.WaitAndRetryAsync(
3, // Anzahl der Versuche
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), // Exponentielle Verzögerung
onRetry: (exception, timeSpan, retryCount, context) =>
{
Console.WriteLine($"Versuch {retryCount} fehlgeschlagen. Wiederholung in {timeSpan.Seconds} Sek. Fehler: {exception.Message}");
}
);
}
public async Task<string> GetDataAsync(string url)
{
// Ausführen der Anfrage mit der Richtlinie
return await _retryPolicy.ExecuteAsync(async () =>
{
var response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
});
}
}
// Verwendung
public class Program
{
public static async Task Main()
{
var client = new ApiClient();
try
{