Поделиться через


Общие сведения о устойчивой разработке приложений

Устойчивость — это возможность приложения восстанавливаться после временных сбоев и продолжать функционировать. В контексте программирования .NET устойчивость достигается путем разработки приложений, которые могут эффективно обрабатывать сбои и быстро восстанавливаться. Чтобы помочь создать устойчивые приложения в .NET, в NuGet доступны следующие два пакета:

Пакет NuGet Описание
📦 Microsoft.Extensions.Resilience Этот пакет NuGet предоставляет механизмы защиты приложений от временных сбоев.
📦 Microsoft.Extensions.Http.Resilience Этот пакет NuGet предоставляет механизмы устойчивости специально для HttpClient класса.

Эти два пакета NuGet построены на основе Polly, который является популярным проектом с открытым исходным кодом. Polly — это библиотека устойчивости .NET и временной обработки ошибок, которая позволяет разработчикам выражать такие стратегии, как повторные попытки, автоматический выключатель, тайм-аут, изоляция отсеков, ограничение скорости, откат и хеджирование в удобной и потокобезопасной форме.

Это важно

Пакет NuGet Microsoft.Extensions.Http.Polly устарел. Вместо этого используйте любой из указанных выше пакетов.

Начало работы

Чтобы приступить к работе с устойчивостью в .NET, установите пакет NuGet Microsoft.Extensions.Resilience .

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

Дополнительные сведения см. в разделе dotnet package add или Управление зависимостями пакетов в приложениях .NET.

Создание конвейера устойчивости

Чтобы использовать устойчивость, необходимо сначала создать конвейер стратегий на основе устойчивости. Каждая настроенная стратегия выполняется в порядке конфигурации. Иными словами, порядок важен. Точка входа — это метод расширения типа IServiceCollection с именем AddResiliencePipeline. Этот метод принимает идентификатор конвейера и делегат, который настраивает конвейер. Делегату передается экземпляр ResiliencePipelineBuilder, который используется для добавления стратегий устойчивости в конвейер.

Рассмотрим следующий пример на основе 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));
});

Предыдущий код:

  • Создает новый экземпляр ServiceCollection.
  • Определяет key, чтобы идентифицировать конвейер.
  • Добавляет конвейер устойчивости к ServiceCollection экземпляру.
  • Настраивает конвейер с помощью стратегий повторных попыток и времени ожидания.

Каждый конвейер настраивается для заданного key, и каждый key используется для идентификации соответствующего ResiliencePipeline конвейера при получении конвейера от поставщика. Параметр key метода является параметром обобщённого типа AddResiliencePipeline.

Расширения построителя конвейеров устойчивости

Чтобы добавить стратегию в конвейер, вызовите любой из доступных Add* методов расширения в экземпляре ResiliencePipelineBuilder .

  • AddRetry: Повторите попытку, если что-то не удалось, что бывает полезно, когда проблема временна и может исчезнуть.
  • AddCircuitBreaker: Перестаньте пытаться, если что-то сломано или занято, что поможет вам избежать напрасной траты времени и усугубления ситуации.
  • AddTimeout: Откажитесь, если что-то занимает слишком много времени, что может повысить производительность за счет освобождения ресурсов.
  • AddRateLimiter: ограничьте количество принятых запросов, что позволяет управлять входящей нагрузкой.
  • AddConcurrencyLimiter: ограничить количество выполняемых запросов, что позволяет управлять исходящей нагрузкой.
  • AddFallback: сделайте что-то другое при возникновении сбоев, что улучшает взаимодействие с пользователем.
  • AddHedging: выдача нескольких запросов в случае высокой задержки или сбоя, что может повысить скорость реагирования.

Дополнительные сведения см. в статье "Стратегии устойчивости". Примеры см. в статье "Создание устойчивых HTTP-приложений: ключевые шаблоны разработки".

Обогащение метрик

Обогащение — это автоматическое расширение телеметрии с известным состоянием в виде пар name/value. Например, приложение может выдавать журнал, включающий операцию и код результата в виде столбцов, которые представляют результат некоторых операций. В этой ситуации и в зависимости от периферийного контекста обогащение добавляет имя кластера, имя процесса, регион, идентификатор клиента и многое другое в журнал по мере отправки в серверную часть телеметрии. При добавлении обогащения код приложения не требует дополнительных действий, чтобы воспользоваться обогащенными метриками.

Как работает обогащение

Представьте, что 1000 глобально распределенных экземпляров служб создают журналы и метрики. При возникновении проблемы на панели мониторинга службы важно быстро определить проблемный регион или центр обработки данных. Обогащение гарантирует, что записи метрик содержат необходимые сведения для выявления сбоев в распределенных системах. Без обогащения нагрузка попадает на код приложения для внутреннего управления этим состоянием, интеграции его в процесс ведения журнала и передачи вручную. Обогащение упрощает этот процесс, легко обрабатывая его, не влияя на логику приложения.

В случае устойчивости при добавлении обогащения в исходящие данные телеметрии добавляются следующие измерения:

  • error.type: версия информации об исключении с низкой степенью уникальности.
  • request.name: имя запроса.
  • request.dependency.name: имя зависимости.

В основе обогащения устойчивости лежит телеметрия Polly MeteringEnricher. Дополнительные сведения см. в разделе Polly: улучшение функций измерения.

Добавить обогащение устойчивости

Помимо регистрации конвейера устойчивости, можно также зарегистрировать обогащение устойчивости. Чтобы добавить обогащение, вызовите метод расширения AddResilienceEnricher(IServiceCollection) на экземпляре IServiceCollection.

services.AddResilienceEnricher();

Вызывая метод расширения AddResilienceEnricher, вы добавляете дополнительные измерения поверх тех, которые по умолчанию встроены в базовую библиотеку Polly. Добавлены следующие измерения обогащения:

  • Обогащение исключений, основанное на IExceptionSummarizer, которое обеспечивает механизм для суммирования исключений при использовании в телеметрии. Дополнительные сведения см. в разделе "Сводка исключений".
  • Обогащение метаданных запроса на основе RequestMetadata, который содержит метаданные запроса для телеметрии. Дополнительные сведения см. в разделе Polly: метрики телеметрии.

Используй конвейер устойчивости

Чтобы использовать настроенный канал отказоустойчивости, необходимо получить его из ResiliencePipelineProvider<TKey>. При добавлении конвейера ранее key был типа string, поэтому необходимо получить конвейер из ResiliencePipelineProvider<string>.

using ServiceProvider provider = services.BuildServiceProvider();

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

ResiliencePipeline pipeline = pipelineProvider.GetPipeline(key);

Предыдущий код:

  • Создает объект ServiceProvider из экземпляра ServiceCollection .
  • ResiliencePipelineProvider<string> Получает от поставщика услуг.
  • Извлекает ResiliencePipeline из ResiliencePipelineProvider<string>.

Выполнение конвейера устойчивости

Чтобы использовать конвейер устойчивости, вызовите любой из доступных Execute* методов в экземпляре ResiliencePipeline . Например, рассмотрим пример вызова ExecuteAsync метода:

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

    return ValueTask.CompletedTask;
});

Предыдущий код выполняет делегат в методе ExecuteAsync . При возникновении сбоев выполняются настроенные стратегии. Например, если параметр RetryStrategy настроен на три повторные попытки, делегат выполняется четыре раза (одна начальная попытка плюс три повторные попытки) перед распространением сбоя.

Дальнейшие действия