Freigeben über


Einführung in die robuste App-Entwicklung

Resilienz ist die Fähigkeit einer App, aus vorübergehenden Fehlern wiederherzustellen und weiterhin funktionieren zu können. Im Kontext der .NET-Programmierung wird resilienz durch das Entwerfen von Apps erreicht, die Fehler ordnungsgemäß verarbeiten und schnell wiederherstellen können. Um stabile Apps in .NET zu erstellen, stehen die folgenden beiden Pakete unter NuGet zur Verfügung:

NuGet-Paket BESCHREIBUNG
📦 Microsoft.Extensions.Resilience Dieses NuGet-Paket bietet Mechanismen zum Abhärten von Apps gegen vorübergehende Fehler.
📦 Microsoft.Extensions.Http.Resilience Dieses NuGet-Paket bietet Resilienzmechanismen speziell für die HttpClient Klasse.

Diese beiden NuGet-Pakete basieren auf Polly, einem beliebten Open-Source-Projekt. Polly ist eine .NET-Resilienz- und vorübergehende Fehlerbehandlungsbibliothek, mit der Entwickler Strategien wie Wiederholen, Circuitbreaker, Timeout, Bulkhead Isolation, Ratenbegrenzung, Fallback und Hedging fließend und threadsicher ausdrücken können.

Von Bedeutung

Das Microsoft.Extensions.Http.Polly NuGet-Paket ist veraltet. Verwenden Sie stattdessen eines der oben genannten Pakete.

Loslegen

Installieren Sie das NuGet-Paket "Microsoft.Extensions.Resilience NuGet", um mit der Resilienz in .NET zu beginnen.

dotnet add package Microsoft.Extensions.Resilience

Weitere Informationen finden Sie unter dotnet package add or Manage package dependencies in .NET applications.

Erstellen einer Ausfallsicherheitspipeline

Um Resilienz zu verwenden, müssen Sie zunächst eine Pipeline mit Resilienz-basierten Strategien erstellen. Jede konfigurierte Strategie wird in der Reihenfolge der Konfiguration ausgeführt. Mit anderen Worten, Reihenfolge ist wichtig. Der Einstiegspunkt ist eine Erweiterungsmethode für den IServiceCollection Typ namens AddResiliencePipeline. Diese Methode verwendet einen Bezeichner der Pipeline und einen Delegaten, der die Pipeline konfiguriert. Dem Delegat wird eine Instanz von ResiliencePipelineBuilder übergeben, die dazu verwendet wird, der Pipeline Resilienzstrategien hinzuzufügen.

Betrachten Sie das folgende zeichenfolgenbasierte key Beispiel:

using Microsoft.Extensions.DependencyInjection;
using Polly;
using Polly.CircuitBreaker;
using Polly.Registry;
using Polly.Retry;
using Polly.Timeout;

var services = new ServiceCollection();

const string key = "Retry-Timeout";

services.AddResiliencePipeline(key, static builder =>
{
    // See: https://www.pollydocs.org/strategies/retry.html
    builder.AddRetry(new RetryStrategyOptions
    {
        ShouldHandle = new PredicateBuilder().Handle<TimeoutRejectedException>()
    });

    // See: https://www.pollydocs.org/strategies/timeout.html
    builder.AddTimeout(TimeSpan.FromSeconds(1.5));
});

Der vorherige Code:

  • Erstellt eine neue ServiceCollection-Instanz.
  • Definiert eine key, um die Pipeline zu identifizieren.
  • Fügt der ServiceCollection Instanz eine Resilienzpipeline hinzu.
  • Konfiguriert die Pipeline mit einer Wiederholungs- und Timeoutstrategie.

Jede Pipeline wird für ein bestimmtes key konfiguriert, und jedes key wird verwendet, um das entsprechende ResiliencePipeline zu identifizieren, wenn Sie die Pipeline vom Anbieter erhalten. Dies key ist ein generischer Typparameter der AddResiliencePipeline Methode.

Erweiterungen für Resilience Pipeline-Builder

Um der Pipeline eine Strategie hinzuzufügen, rufen Sie eine der verfügbaren Add* Erweiterungsmethoden für die ResiliencePipelineBuilder Instanz auf.

  • AddRetry: Versuchen Sie es erneut, wenn etwas fehlschlägt, was hilfreich ist, wenn das Problem vorübergehend ist und möglicherweise abläuft.
  • AddCircuitBreaker: Versuchen Sie nicht, wenn etwas kaputt oder ausgelastet ist, da es Ihnen zugute kommt, verschwendete Zeit zu vermeiden und eine Verschlimmerung der Situation zu verhindern.
  • AddTimeout: Geben Sie auf, wenn etwas zu lange dauert, was die Leistung verbessern kann, indem Sie Ressourcen freigeben.
  • AddRateLimiter: Beschränken Sie die Anzahl der anforderungen, die Sie akzeptieren, wodurch Sie eingehende Last steuern können.
  • AddConcurrencyLimiter: Beschränken Sie die Anzahl der anforderungen, die Sie vornehmen, wodurch Sie die ausgehende Last steuern können.
  • AddFallback: Führen Sie etwas anderes aus, wenn Fehler auftreten, wodurch die Benutzererfahrung verbessert wird.
  • AddHedging: Stellen Sie bei hoher Latenz oder fehlern mehrere Anforderungen aus, die die Reaktionsfähigkeit verbessern können.

Weitere Informationen finden Sie unter Resilienzstrategien. Beispiele finden Sie unter Erstellen robuster HTTP-Apps: Wichtige Entwicklungsmuster.

Metriken-Anreicherung

Anreicherung bezeichnet die automatische Erweiterung der Telemetrie durch Hinzufügen bekannter Zustände in Form von Namen/Wert-Paaren. Beispielsweise kann eine App ein Protokoll ausgeben, das den Vorgang und den Ergebniscode als Spalten enthält, um das Ergebnis eines Vorgangs darzustellen. In dieser Situation und je nach peripherem Kontext fügt die Anreicherung Clustername, Prozessname, Region, Mandanten-ID und mehr zum Protokoll hinzu, während sie an das Telemetrie-Back-End gesendet wird. Wenn Anreicherung hinzugefügt wird, muss der App-Code nichts zusätzlich tun, um von angereicherten Metriken zu profitieren.

Funktionsweise der Anreicherung

Stellen Sie sich vor, dass 1.000 global verteilte Dienstinstanzen Protokolle und Metriken generieren. Wenn auf Ihrem Dienstdashboard ein Problem auftritt, ist es wichtig, die problematische Region oder das Rechenzentrum schnell zu identifizieren. Anreicherung stellt sicher, dass Metrikdatensätze die erforderlichen Informationen zum Anheften von Fehlern in verteilten Systemen enthalten. Ohne Anreicherung fällt der Aufwand auf den App-Code, um diesen Zustand intern zu verwalten, in den Protokollierungsprozess zu integrieren und manuell zu übertragen. Die Anreicherung vereinfacht diesen Prozess, ohne dass sich dies auf die Logik der App auswirkt.

Im Falle der Resilienz werden beim Hinzufügen der Anreicherung die folgenden Dimensionen zur ausgehenden Telemetrie hinzugefügt:

  • error.type: Version einer Information einer Ausnahme mit geringer Kardinalität.
  • request.name: Der Name der Anforderung.
  • request.dependency.name: Der Name der Abhängigkeit.

Die Resilienzanreicherung wird im Hintergrund über Pollys Telemetriedaten MeteringEnricher durchgeführt. Weitere Informationen finden Sie unter Polly: Metering Enrichment.

Hinzufügen von Resilienzanreicherung

Zusätzlich zur Registrierung einer Resilienzpipeline können Sie auch resilienzerweiterungen registrieren. Rufen Sie zum Hinzufügen einer Anreicherung die AddResilienceEnricher(IServiceCollection) Erweiterungsmethode für die IServiceCollection Instanz auf.

services.AddResilienceEnricher();

Indem Sie die AddResilienceEnricher Erweiterungsmethode aufrufen, fügen Sie über den Standarddimensionen, die in die zugrunde liegende Polly-Bibliothek integriert sind, Dimensionen hinzu. Die folgenden Anreicherungsdimensionen werden hinzugefügt:

  • Ausnahmeanreicherung basierend auf dem IExceptionSummarizer, der einen Mechanismus zum Zusammenfassen von Ausnahmen für die Verwendung in Telemetrie bereitstellt. Weitere Informationen finden Sie unter "Exception-Zusammenfassung".
  • Anfordern der Metadatenanreicherung basierend auf RequestMetadata, in der die Anforderungsmetadaten für Telemetrie enthalten sind. Weitere Informationen finden Sie unter Polly: Telemetriemetriken.

Verwenden Sie die Resilienz-Pipeline

Um eine konfigurierte Resilienzpipeline zu verwenden, müssen Sie die Pipeline aus einem ResiliencePipelineProvider<TKey> abrufen. Wenn Sie die Pipeline zuvor hinzugefügt haben, war die key vom Typ string, sodass Sie die Pipeline aus der ResiliencePipelineProvider<string> beziehen müssen.

using ServiceProvider provider = services.BuildServiceProvider();

ResiliencePipelineProvider<string> pipelineProvider =
    provider.GetRequiredService<ResiliencePipelineProvider<string>>();

ResiliencePipeline pipeline = pipelineProvider.GetPipeline(key);

Der vorherige Code:

  • Erstellt ein ServiceProvider basierend auf der ServiceCollection Instanz.
  • Ruft den ResiliencePipelineProvider<string> aus dem Dienstanbieter ab.
  • Die Methode ruft die ResiliencePipeline aus dem ResiliencePipelineProvider<string> ab.

Ausführen der Resilienzpipeline

Um die Resilienzpipeline zu verwenden, rufen Sie eine der verfügbaren Execute* Methoden für die ResiliencePipeline Instanz auf. Zum Beispiel, betrachten Sie einen Beispielaufruf der ExecuteAsync Methode.

await pipeline.ExecuteAsync(static cancellationToken =>
{
    // Code that could potentially fail.

    return ValueTask.CompletedTask;
});

Der vorangehende Code führt den Delegaten innerhalb der ExecuteAsync-Methode aus. Wenn Fehler auftreten, werden die konfigurierten Strategien ausgeführt. Wenn die RetryStrategy beispielsweise so konfiguriert wird, dass sie dreimal ausgeführt wird, wird der Delegat vor der Weiterleitung des Fehlers viermal ausgeführt (ein erster Versuch plus drei Wiederholungsversuche).

Nächste Schritte