Neu in .NET 8.0 [26]: Anpassung der Resilienz im HTTP-Client

Entwicklerinnen und Entwickler können eigene Polly-Pipelines zur Handhabung von Fehlersituationen definieren.

In Pocket speichern vorlesen Druckansicht 1 Kommentar lesen

(Bild: sirtravelalot/Shutterstock.com)

Lesezeit: 1 Min.
Von
  • Dr. Holger Schwichtenberg

Die vorherige Ausgabe dieser Blogserie zu .NET 8.0 hat AddStandardResilienceHandler() vorgestellt. In diesem Beitrag geht es um die Anpassung der Standardeinstellungen.

Der Dotnet-Doktor – Holger Schwichtenberg

Dr. Holger Schwichtenberg ist technischer Leiter des Expertennetzwerks www.IT-Visions.de, das mit 53 renommierten Experten zahlreiche mittlere und große Unternehmen durch Beratungen und Schulungen sowie bei der Softwareentwicklung unterstützt. Durch seine Auftritte auf zahlreichen nationalen und internationalen Fachkonferenzen sowie mehr als 90 Fachbücher und mehr als 1500 Fachartikel gehört Holger Schwichtenberg zu den bekanntesten Experten für .NET und Webtechniken in Deutschland.

Alternativ zu AddStandardResilienceHandler() kann man via AddResilienceHandler() eine komplett eigene Polly-Pipeline definieren. Abbildung 1 zeigt die standardmäßige Pipeline.

Der Standard-Handler erledigt fünf Aufgaben in einer sogenannten Pipeline (Abb. 1).

(Bild: Microsoft)

Die folgende selbstdefinierte Pipeline verwendet nur die Aufträge 2 bis 5 aus obiger Tabelle mit folgenden Einstellungen:

  • Geamtanforderungs-Timeout: 10 Sekunden
  • Wiederholen: Der Aufruf wird bis zu fünfmal wiederholt. Der Abstand zwischen den Versuchen ist konstant 1 Sekunde. Bei dem Versuch gibt es eine Bildschirmausgabe.
  • Trennschalter: Abbruch, wenn in 10 Sekunden 50 % der Anfragen fehlschlagen, frühestens aber nach 5 Anfragen
  • Versuchs-Timeout: 2 Sekunden
services.AddHttpClient<WeatherServiceClient>(
  // Timeout insgesamt: Hier 10 Sekunden
  client => { client.Timeout = new TimeSpan(0,0,10); })
  .AddResilienceHandler(
   "CustomPipeline",
   static builder =>
   {
   // Wiederholungen bei Fehlern
   // Hier: Der Aufruf wird bis zu fünf Mal wiederholt. Der Abstand zwischen den Versuchen ist konstant 1 Sekunde. Bei dem Versuch gibt es eine Bildschirmausgabe.
   // https://www.pollydocs.org/strategies/retry.html
   builder.AddRetry(new HttpRetryStrategyOptions
    {
     // Customize and configure the retry logic.
     BackoffType = DelayBackoffType.Constant, // oder Linear oder Exponential
     Delay = TimeSpan.FromSeconds(1),
     MaxRetryAttempts = 10,
 
     OnRetry = static (args) =>
     {
      CUI.Cyan($"{DateTime.Now.ToLongTimeString()} Versuch #{args.AttemptNumber} Zeit seit letztem Versuch:{(int)(DateTime.Now - lastTry).TotalMilliseconds} ms Dauer:{args.Duration} Grund:{args.Outcome.Result} \n");
      lastTry = DateTime.Now;
      return ValueTask.CompletedTask;
     },
    });
 
    // Trennschalter, wenn zu viele Fehler passieren
    // Hier: Abbruch wenn in 10 Sekunden 50% der Anfragen fehlschlagen, frühestens aber nach 5 Anfragen
    // https://www.pollydocs.org/strategies/circuit-breaker.html
    builder.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions
    {
     // Customize and configure the circuit breaker logic.
     SamplingDuration = TimeSpan.FromSeconds(10),
     FailureRatio = 0.5,
     MinimumThroughput = 5,
     ShouldHandle = static args =>
     {
      return ValueTask.FromResult(args is
      {
       Outcome.Result.StatusCode: HttpStatusCode.RequestTimeout or HttpStatusCode.TooManyRequests or HttpStatusCode.InternalServerError
      });
     }
    });
 
    // Timeout für einzelne Versuche
    // hier: 2 Sekunden
    // https://www.pollydocs.org/strategies/timeout.html
    builder.AddTimeout(TimeSpan.FromSeconds(2));
   });

(rme)