- Closed(闭合):正常请求
- Open(打开):熔断,直接返回错误
- Half-Open(半开):尝试恢复
Closed → (失败率>阈值) → Open
Open → (超时) → Half-Open
Half-Open → (成功) → Closed
Half-Open → (失败) → Open
package main
import (
"errors"
"sync"
"time"
)
type State int
const (
StateClosed State = iota
StateOpen
StateHalfOpen
)
type CircuitBreaker struct {
maxFailures int
timeout time.Duration
state State
failures int
lastFailTime time.Time
mu sync.Mutex
}
func NewCircuitBreaker(maxFailures int, timeout time.Duration) *CircuitBreaker {
return &CircuitBreaker{
maxFailures: maxFailures,
timeout: timeout,
state: StateClosed,
}
}
func (cb *CircuitBreaker) Call(fn func() error) error {
cb.mu.Lock()
defer cb.mu.Unlock()
// 检查是否可以从Open切换到Half-Open
if cb.state == StateOpen {
if time.Since(cb.lastFailTime) > cb.timeout {
cb.state = StateHalfOpen
} else {
return errors.New("circuit breaker is open")
}
}
// 执行请求
err := fn()
if err != nil {
cb.onFailure()
return err
}
cb.onSuccess()
return nil
}
func (cb *CircuitBreaker) onSuccess() {
cb.failures = 0
cb.state = StateClosed
}
func (cb *CircuitBreaker) onFailure() {
cb.failures++
cb.lastFailTime = time.Now()
if cb.failures >= cb.maxFailures {
cb.state = StateOpen
}
}func GetUserWithFallback(userID string) (*User, error) {
cb := GetCircuitBreaker("user-service")
err := cb.Call(func() error {
user, err := userService.GetUser(userID)
if err != nil {
return err
}
return nil
})
if err != nil {
// 降级:返回缓存数据
return cache.GetUser(userID)
}
return user, nil
}关键要点:
- ✅ 熔断防止雪崩
- ✅ 三种状态自动切换
- ✅ 降级保证可用性
- ✅ 监控熔断指标