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

Что такое Cirquit Breaker?

2.0 Middle🔥 241 комментариев
#Микросервисы и архитектура

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

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

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

Что такое Circuit Breaker (Автоматический выключатель)

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

Основная проблема, которую решает Circuit Breaker

В микросервисной архитектуре сервисы постоянно взаимодействуют друг с другом через сетевые вызовы. Если один сервис становится медленным или недоступным, это может привести к:

  • Накоплению незавершённых запросов у клиентов
  • Исчерпанию ресурсов (пулы потоков, соединения)
  • Распространению сбоя на другие сервисы (каскадный отказ)

Состояния Circuit Breaker

Паттерн реализует конечный автомат с тремя основными состояниями:

  1. Closed (Закрыто) — нормальный режим работы. Все запросы проходят к удалённому сервису. При этом ведётся подсчёт ошибок.
type CircuitBreaker struct {
    failures     int
    threshold    int
    state        State
    resetTimeout time.Duration
}

// В состоянии Closed запросы выполняются нормально
func (cb *CircuitBreaker) Execute(req func() error) error {
    if cb.state == StateClosed {
        err := req()
        if err != nil {
            cb.failures++
            if cb.failures >= cb.threshold {
                cb.trip() // Переход в состояние Open
            }
        }
        return err
    }
    // ... обработка других состояний
}
  1. Open (Разомкнуто) — при достижении порога ошибок цепь "разрывается". Все запросы немедленно завершаются ошибкой без обращения к удалённому сервису.
func (cb *CircuitBreaker) Execute(req func() error) error {
    switch cb.state {
    case StateOpen:
        // Немедленный возврат ошибки без вызова сервиса
        return ErrCircuitOpen
    // ... другие состояния
    }
}
  1. Half-Open (Полуразомкнуто) — после таймаута автоматический выключатель позволяет ограниченному количеству "пробных" запросов. Если они успешны — возврат в состояние Closed, если нет — снова Open.
func (cb *CircuitBreaker) Execute(req func() error) error {
    switch cb.state {
    case StateHalfOpen:
        // Пробный запрос для проверки восстановления сервиса
        err := req()
        if err == nil {
            cb.reset() // Возврат в Closed
        } else {
            cb.trip() // Снова Open
        }
        return err
    // ... другие состояния
    }
}

Ключевые параметры настройки

  • Failure threshold — порог ошибок для перехода в состояние Open
  • Reset timeout — время ожидания перед переходом из Open в Half-Open
  • Half-open max calls — максимальное количество пробных запросов в состоянии Half-Open

Реализация в Go

В Go существует несколько популярных библиотек для реализации Circuit Breaker:

// Пример с использованием библиотеки sony/gobreaker
import "github.com/sony/gobreaker"

func main() {
    cb := gobreaker.NewCircuitBreaker(gobreaker.Settings{
        Name:        "user-service",
        MaxRequests: 5,           // Максимум запросов в Half-Open
        Interval:    10 * time.Second, // Сброс статистики
        Timeout:     15 * time.Second, // Таймаут в состоянии Open
        ReadyToTrip: func(counts gobreaker.Counts) bool {
            // Переход в Open при 5 последовательных ошибках
            return counts.ConsecutiveFailures > 5
        },
    })
    
    // Использование
    _, err := cb.Execute(func() (interface{}, error) {
        // Вызов удалённого сервиса
        return userService.GetUser(id)
    })
}

Преимущества использования

  • Предотвращение каскадных сбоев — изоляция проблемных сервисов
  • Снижение нагрузки на проблемный сервис, давая ему время на восстановление
  • Улучшение отзывчивости — быстрый возврат ошибки вместо долгого ожидания таймаута
  • Возможность graceful degradation — переход на запасные функции или кэшированные данные

Практические рекомендации

  1. Настройка параметров должна учитывать конкретные SLA сервиса
  2. Мониторинг состояний Circuit Breaker через метрики и алерты
  3. Комбинация с другими паттернами — Retry, Fallback, Timeout
  4. Логирование переходов между состояниями для диагностики
  5. Тестирование поведения при сбоях (chaos engineering)

Пример комплексного использования

func getUserWithResilience(userID string) (*User, error) {
    var result *User
    
    err := cb.Execute(func() (interface{}, error) {
        // Основной вызов сервиса
        return userService.GetUser(userID)
    })
    
    if err != nil {
        // Fallback: возврат кэшированных данных или заглушки
        log.Printf("Circuit breaker open, using cache: %v", err)
        return cache.GetUser(userID)
    }
    
    return result, nil
}

Circuit Breaker является критически важным компонентом для построения устойчивых распределённых систем на Go, особенно в контексте микросервисной архитектуры. Его правильная реализация и настройка позволяют значительно повышать доступность системы в условиях частичных отказов.