← Назад к вопросам

Как работает Polly для обработки transient faults? Что такое Circuit Breaker и Retry паттерны?

2.0 Middle🔥 162 комментариев
#ООП и паттерны проектирования

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как работает Polly для обработки transient faults?

Polly — это библиотека для .NET, предназначенная для реализации стратегий устойчивости приложения, особенно для обработки transient faults (временных ошибок). Эти ошибки возникают из-за кратковременных проблем в сетевых соединениях, временной недоступности служб или временных ограничений ресурсов, и они обычно могут быть устранены повторными попытками. Polly предоставляет декларативный способ определения политик устойчивости, таких как Retry, Circuit Breaker, Timeout, Fallback и Bulkhead.

Основные механизмы Polly

Polly работает через создание и применение политик к выполняемым операциям. Вот ключевые шаги:

  1. Определение политики: Вы создаете политику, например, для повторных попыток или размыкания цепи.
  2. Применение политики: Политика "оборачивает" выполнение функции или делегата, содержащего потенциально неустойчивый код.
  3. Обработка исключений: Политика отслеживает исключения и, основываясь на условиях, выполняет действия (повторные попытки, размыкание цепи и т.д.).

Пример создания политики повторных попыток:

using Polly;
using Polly.Retry;

// Определяем политику повторных попыток: 3 попытки с экспоненциальной задержкой
var retryPolicy = Policy
    .Handle<HttpRequestException>() // Обрабатываем исключения HTTP
    .Or<TimeoutException>()         // Или исключения времени ожидания
    .WaitAndRetry(3, retryAttempt => 
        TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); // Задержка: 2, 4, 8 секунд

// Применяем политику к операции
retryPolicy.Execute(() =>
{
    // Код, который может вызвать transient fault, например, HTTP запрос
    HttpClient client = new HttpClient();
    var response = client.GetAsync("https://api.example.com/data").Result;
    // Обработка ответа...
});

Polly также поддерживает асинхронные операции через AsyncPolicy, что особенно важно для современных backend-приложений.

Что такое Circuit Breaker и Retry паттерны?

Retry (Повторная попытка)

Паттерн Retry — это стратегия, при которой операция повторяется в случае временной ошибки, чтобы повысить вероятность успешного выполнения. Это особенно полезно для transient faults, которые могут исчезнуть через короткое время.

Ключевые параметры Retry в Polly:

  • Количество попыток: Сколько раз повторять операцию.
  • Задержка между попытками: Фиксированная, экспоненциальная или случайная.
  • Условия обработки: Какие исключения запускают повторную попытку.

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

Circuit Breaker (Размыкатель цепи)

Паттерн Circuit Breaker — это механизм для предотвращения непрерывных повторных попыток при постоянных ошибках, которые могут указывать на более серьезную проблему (например, полный сбой службы). Он работает аналогично электрическому размыкателю цепи: после определенного количества ошибок "цепь размыкается", и дальнейшие попытки блокируются на период времени, позволяя системе восстановиться.

Состояния Circuit Breaker в Polly:

  1. Closed (Замкнуто): Операции выполняются нормально. Ошибки отслеживаются.
  2. Open (Разомкнуто): После достижения порога ошибок (например, 5 исключений за 10 секунд) цепь размыкается. Все новые операции немедленно выбрасывают исключение без попытки выполнения.
  3. Half-Open (Полуразомкнуто): После периода времени (например, 30 секунд) цепь переходит в это состояние. Ограниченное количество тестовых операций разрешено; если они успешны, цепь снова замыкается, если неуспешны — размыкается.

Пример определения Circuit Breaker в Polly:

using Polly;
using Polly.CircuitBreaker;

// Создаем политику Circuit Breaker: размыкается после 5 исключений за 10 секунд, время размыкания 30 секунд
var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(5, TimeSpan.FromSeconds(10), 
        onBreak: (exception, breakDelay) => 
            Console.WriteLine($"Circuit broken for {breakDelay.TotalSeconds} seconds due to: {exception.Message}"),
        onReset: () => Console.WriteLine("Circuit reset!"),
        onHalfOpen: () => Console.WriteLine("Circuit half-open: testing..."));

// Применение
try
{
    circuitBreakerPolicy.Execute(() =>
    {
        // Код операции
        PerformNetworkCall();
    });
}
catch (BrokenCircuitException ex)
{
    // Обработка исключения, когда цепь разомкнута
    Console.WriteLine("Operation blocked due to broken circuit.");
}

Сочетание Retry и Circuit Breaker

В реальных сценариях эти паттерны часто используются вместе: Retry для обработки случайных transient faults, и Circuit Breaker для защиты системы при длительных сбоях. Polly позволяет легко комбинировать политики через PolicyWrap.

// Комбинирование: сначала Retry, затем Circuit Breaker
var combinedPolicy = Policy.Wrap(retryPolicy, circuitBreakerPolicy);

combinedPolicy.Execute(() =>
{
    // Ваша неустойчивая операция
    CallExternalService();
});

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

Как работает Polly для обработки transient faults? Что такое Circuit Breaker и Retry паттерны? | PrepBro