Sobes.tech
Senior

Ο φορτωτής πρέπει να καταλαβαίνει ότι το backend απαντά με σφάλματα, και όταν υπερβαίνει ένα όριο για ένα συγκεκριμένο χρονικό διάστημα, να το αποκλείει από την ισορροπία (Circuit Breaker)

sobes.tech AI

Απάντηση από AI

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

Основные шаги:

  1. Хранить для каждого бэкенда счётчик ошибок и состояние (Closed, Open, Half-Open).
  2. При ошибках увеличивать счётчик.
  3. Если количество ошибок превышает порог за заданный интервал, переводить состояние в Open — бэкенд исключается.
  4. Через некоторое время переводить в Half-Open — пробовать отправлять запросы.
  5. Если запросы успешны — переводить в Closed, сбрасывая счётчики.

Пример упрощённой структуры:

type CircuitBreaker struct {
    failureCount int
    state        string // "Closed", "Open", "Half-Open"
    lastFailure  time.Time
    mutex        sync.Mutex
}

func (cb *CircuitBreaker) AllowRequest() bool {
    cb.mutex.Lock()
    defer cb.mutex.Unlock()
    if cb.state == "Open" && time.Since(cb.lastFailure) < cooldown {
        return false
    }
    if cb.state == "Open" {
        cb.state = "Half-Open"
    }
    return true
}

func (cb *CircuitBreaker) ReportResult(success bool) {
    cb.mutex.Lock()
    defer cb.mutex.Unlock()
    if success {
        cb.failureCount = 0
        cb.state = "Closed"
    } else {
        cb.failureCount++
        cb.lastFailure = time.Now()
        if cb.failureCount >= failureThreshold {
            cb.state = "Open"
        }
    }
}

Балансер при распределении запросов проверяет AllowRequest() для каждого бэкенда и исключает те, у которых состояние "Open".