Polly и Microsoft.Extensions.Resilience

↑ 7.3 Надёжность и отказоустойчивость · ← Предыдущая · → Следующая

Желательно~3 мин чтенияУровень: senior

Зачем это на собесе

Практика: как реализовать паттерны устойчивости в .NET без ручного кода.

Объяснение

Polly v8 предоставляет ResiliencePipeline, а пакеты Microsoft.Extensions.Http.Resilience и Microsoft.Extensions.Resilience интегрируют его с DI и HttpClient.

СтратегияНазначение
Retryповторы с backoff и jitter
Circuit breakerразмыкание при сбоях
Timeoutограничение времени попытки
Hedgingпараллельные запросы для снижения хвостовой задержки
Fallbackзапасное значение
Rate limiter, Concurrency limiterограничение нагрузки
// Готовый набор для HttpClient: rate limiter → total timeout → retry → circuit breaker → attempt timeout
builder.Services.AddHttpClient<IBilling, BillingClient>().AddStandardResilienceHandler();
 
// Своя настройка
builder.Services.AddHttpClient("pay").AddResilienceHandler("pay", b => b
    .AddRetry(new HttpRetryStrategyOptions { MaxRetryAttempts = 3, BackoffType = DelayBackoffType.Exponential, UseJitter = true, Delay = TimeSpan.FromMilliseconds(200) })
    .AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions { SamplingDuration = TimeSpan.FromSeconds(30), FailureRatio = 0.5, MinimumThroughput = 20, BreakDuration = TimeSpan.FromSeconds(15) })
    .AddTimeout(TimeSpan.FromSeconds(3)));
 
// Для произвольного кода
builder.Services.AddResiliencePipeline("db", p => p.AddRetry(new() { MaxRetryAttempts = 2 }).AddTimeout(TimeSpan.FromSeconds(5)));
public class Repo([FromKeyedServices("db")] ResiliencePipeline pipeline) { public Task Run() => pipeline.ExecuteAsync(async ct => { /* ... */ }).AsTask(); }

Метрики и логи стратегий (resilience.polly.*) экспортируются через OpenTelemetry.

Нюансы и подводные камни

  • Порядок стратегий важен: внешний таймаут → retry → breaker → таймаут попытки.
  • Не оборачивайте ретраем неидемпотентные вызовы без ключа.
  • AddStandardResilienceHandler подходит по умолчанию; значения тюнингуйте под SLA зависимости.
  • Не смешивайте старый Polly (v7) и v8 API.
  • Тесты: используйте FakeTimeProvider и управляемые обработчики для проверки ретраев.

Практика

  1. Подключите standard handler и проверьте его метрики.
  2. Настройте hedging для идемпотентного GET.
  3. Напишите тест, проверяющий число попыток при 503.

Вопросы с ответами

Связанные темы