Udostępnij za pośrednictwem


Wprowadzenie do tworzenia odpornych aplikacji

Odporność to zdolność aplikacji do odzyskiwania po przejściowych awariach i kontynuowania działania. W kontekście programowania .NET odporność jest osiągana przez projektowanie aplikacji, które mogą bezpiecznie obsługiwać błędy i szybko odzyskiwać. Aby ułatwić tworzenie odpornych aplikacji na platformie .NET, w programie NuGet są dostępne następujące dwa pakiety:

Pakiet NuGet Opis
📦 Microsoft.Extensions.Resilience Ten pakiet NuGet udostępnia mechanizmy wzmacniania ochrony aplikacji przed przejściowymi awariami.
📦 Microsoft.Extensions.Http.Resilience Ten pakiet NuGet zapewnia mechanizmy odporności specjalnie dla HttpClient klasy.

Te dwa pakiety NuGet są oparte na polly, który jest popularnym projektem open source. Polly to biblioteka odporności platformy .NET i obsługi błędów przejściowych, która umożliwia deweloperom wyrażanie strategii, takich jak ponawianie prób, przełącznik awaryjny, limit czasu, izolacja grodziowa, ograniczanie liczby żądań, rezerwowe rozwiązania i zabezpieczanie, w sposób płynny i bezpieczny wątkowo.

Ważne

Pakiet NuGet Microsoft.Extensions.Http.Polly jest przestarzały. Zamiast tego należy użyć jednego z wyżej wymienionych pakietów.

Rozpocznij

Aby rozpocząć pracę z odpornością na platformie .NET, zainstaluj pakiet NuGet Microsoft.Extensions.Resilience .

dotnet add package Microsoft.Extensions.Resilience --version 8.0.0

Aby uzyskać więcej informacji, zobacz dotnet package add or Manage package dependencies in .NET applications (Dodawanie pakietów dotnet lub zarządzanie zależnościami pakietów w aplikacjach platformy .NET).

Budowanie sieci odporności

Aby korzystać z odporności, należy najpierw utworzyć potok strategii opartych na odporności. Każda skonfigurowana strategia jest wykonywana w kolejności konfiguracji. Innymi słowy, kolejność jest ważna. Punkt wejścia to metoda rozszerzenia typu IServiceCollection o nazwie AddResiliencePipeline. Ta metoda przyjmuje identyfikator potoku i delegata, który konfiguruje potok. Delegatowi jest przekazany egzemplarz ResiliencePipelineBuilder, który służy do dodawania strategii odpornościowych do potoku.

Rozważmy następujący przykład oparty na ciągach key:

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));
});

Poprzedni kod:

  • Tworzy nowy obiekt ServiceCollection.
  • Definiuje element key, aby zidentyfikować potok.
  • Dodaje pipeline odporności do wystąpienia ServiceCollection.
  • Konfiguruje rurociąg z użyciem strategii ponawiania i limitu czasu.

Każdy potok jest skonfigurowany dla danego key, a każdy key jest używany do identyfikowania odpowiadającego mu ResiliencePipeline podczas pobierania potoku od dostawcy. key to parametr ogólny metody AddResiliencePipeline.

Rozszerzenia budowniczego potoku odporności

Aby dodać strategię do potoku, wywołaj dowolną z dostępnych Add* metod rozszerzenia na obiekcie ResiliencePipelineBuilder .

  • AddRetry: Spróbuj ponownie, jeśli coś się nie powiedzie, co jest przydatne, gdy problem jest tymczasowy i może odejść.
  • AddCircuitBreaker: Przestań próbować, jeśli coś jest uszkodzone lub zajęte, co przynosi korzyści, unikając zmarnowanego czasu i pogarszając sytuację.
  • AddTimeout: Zrezygnuj, jeśli coś trwa zbyt długo, co może poprawić wydajność, zwalniając zasoby.
  • AddRateLimiter: Ogranicz liczbę akceptowanych żądań, co umożliwia kontrolowanie obciążenia przychodzącego.
  • AddConcurrencyLimiter: Ogranicz liczbę żądań, które należy wykonać, co umożliwia kontrolowanie obciążenia wychodzącego.
  • AddFallback: Wykonaj coś innego, gdy występują błędy, co poprawia środowisko użytkownika.
  • AddHedging: Wysyłaj wiele żądań w przypadku dużego opóźnienia lub awarii, co może poprawić czas odpowiedzi.

Aby uzyskać więcej informacji, zobacz Strategie odporności. Aby zapoznać się z przykładami, zobacz Tworzenie odpornych aplikacji HTTP: kluczowe wzorce programistyczne.

Wzbogacanie metryk

Wzbogacanie to automatyczne wzbogacenie telemetrii o dobrze znane stany w postaci par nazwa/wartość. Na przykład aplikacja może emitować dziennik zawierający operację i kod wyniku jako kolumny reprezentujące wynik operacji. W tej sytuacji, w zależności od kontekstu otoczenia, proces wzbogacania dodaje nazwę klastra, nazwę procesu, region, identyfikator dzierżawy i inne dane do dziennika, w momencie jego wysłania do zaplecza telemetrii. Po dodaniu wzbogacania kod aplikacji nie musi wykonywać żadnych dodatkowych czynności, aby korzystać z wzbogaconych metryk.

Jak działa wzbogacanie

Wyobraź sobie 1000 globalnie rozproszonych wystąpień usługi generujących dzienniki i metryki. W przypadku wystąpienia problemu na pulpicie nawigacyjnym usługi kluczowe jest szybkie zidentyfikowanie problematycznego regionu lub centrum danych. Wzbogacanie zapewnia, że rekordy metryk zawierają niezbędne informacje, aby wskazać awarie w systemach rozproszonych. Bez wzbogacania obciążenie spada na kod aplikacji w celu wewnętrznego zarządzania tym stanem, zintegrowania go z procesem rejestrowania i ręcznego przesyłania go. Wzbogacanie upraszcza ten proces, płynnie go obsługując, nie wpływając przy tym na logikę aplikacji.

W przypadku rezyliencji do wychodzących danych telemetrycznych dodawane są następujące wymiary, gdy dodaje się wzbogacanie:

  • error.type: wersja o niskiej kardynalności informacji o wyjątku.
  • request.name: nazwa żądania.
  • request.dependency.name: nazwa zależności.

Pod powierzchnią wzbogacanie odporności opiera się na telemetrii Polly MeteringEnricher. Aby uzyskać więcej informacji, zobacz Polly: Wzbogacanie pomiarów.

Dodaj wzmocnienie odporności

Można zarejestrować nie tylko potok odporności, ale również wzbogacenie odporności. Aby dodać rozszerzenie, wywołaj metodę AddResilienceEnricher(IServiceCollection) rozszerzeń na instancji IServiceCollection.

services.AddResilienceEnricher();

Wywołując metodę rozszerzenia AddResilienceEnricher, dodajesz dodatkowe wymiary do domyślnych, wbudowanych w podstawową bibliotekę Polly. Dodajemy następujące elementy wzbogacania:

Korzystanie z mechanizmu odporności

Aby użyć skonfigurowanego potoku resiliencji, należy pobrać potok z elementu ResiliencePipelineProvider<TKey>. Po dodaniu potoku wcześniej, key był typu string, więc musisz pobrać potok z ResiliencePipelineProvider<string>.

using ServiceProvider provider = services.BuildServiceProvider();

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

ResiliencePipeline pipeline = pipelineProvider.GetPipeline(key);

Poprzedni kod:

  • Tworzy element ServiceProvider z ServiceCollection wystąpienia.
  • Pobiera element ResiliencePipelineProvider<string> od dostawcy usług.
  • Pobiera element ResiliencePipeline z obiektu ResiliencePipelineProvider<string>.

Uruchomienie rurociągu odporności

Aby użyć potoku niezawodności, wywołaj dowolną z dostępnych Execute* metod na instancji ResiliencePipeline. Rozważmy na przykład przykładowe wywołanie ExecuteAsync metody:

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

    return ValueTask.CompletedTask;
});

Powyższy kod wykonuje delegata w metodzie ExecuteAsync . W przypadku niepowodzeń są wykonywane skonfigurowane strategie. Jeśli na przykład element RetryStrategy jest skonfigurowany do ponowienia próby trzy razy, delegat jest wykonywany cztery razy (jedna próba początkowa i trzy ponowienia próby) przed propagacją błędu.

Następne kroki