Back to questions
Senior
4
Балансер должен понимать, что бэкенд отвечает ошибками, и при превышении порога на определённое время исключать его из балансировки (Circuit Breaker)
Companies where asked
Яндекс
Answer from AI
sobes.tech AI
Для реализации балансировщика с поддержкой Circuit Breaker на Go нужно отслеживать состояние каждого бэкенда и учитывать количество ошибок за определённый период. При превышении порога ошибок сервис помечается как "отключённый" и исключается из балансировки на время.
Основные шаги:
- Хранить для каждого бэкенда счётчик ошибок и состояние (Closed, Open, Half-Open).
- При ошибках увеличивать счётчик.
- Если количество ошибок превышает порог за заданный интервал, переводить состояние в Open — бэкенд исключается.
- Через некоторое время переводить в Half-Open — пробовать отправлять запросы.
- Если запросы успешны — переводить в 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".