2 回复
熔断器是分布式系统中提升容错性的关键模式,其核心原理是通过监控失败率自动切断故障服务的调用链路。以下是Go语言中实现熔断器的典型方案与代码示例:
核心状态机实现
type CircuitState int
const (
Closed CircuitState = iota // 正常请求
Open // 熔断状态
HalfOpen // 试探恢复
)
type CircuitBreaker struct {
state CircuitState
failureCount int
failureThreshold int
resetTimeout time.Duration
lastFailure time.Time
mutex sync.RWMutex
}
基于时间窗口的统计实现
type WindowedMetrics struct {
requests *ring.Ring // 环形队列记录最近请求
failures *ring.Ring // 环形队列记录最近失败
windowSize int
timeout time.Duration
}
func (wm *WindowedMetrics) Record(result bool) {
wm.requests.Value = time.Now()
if !result {
wm.failures.Value = time.Now()
}
wm.requests = wm.requests.Next()
wm.failures = wm.failures.Next()
}
func (wm *WindowedMetrics) FailureRate() float64 {
now := time.Now()
var total, failed int
for i := 0; i < wm.windowSize; i++ {
if reqTime, ok := wm.requests.Value.(time.Time); ok {
if now.Sub(reqTime) <= wm.timeout {
total++
if failTime, ok := wm.failures.Value.(time.Time); ok {
if now.Sub(failTime) <= wm.timeout {
failed++
}
}
}
}
wm.requests = wm.requests.Next()
wm.failures = wm.failures.Next()
}
if total == 0 {
return 0
}
return float64(failed) / float64(total)
}
完整熔断器示例
func (cb *CircuitBreaker) Execute(req func() (interface{}, error)) (interface{}, error) {
cb.mutex.RLock()
state := cb.state
cb.mutex.RUnlock()
switch state {
case Open:
if time.Since(cb.lastFailure) > cb.resetTimeout {
cb.mutex.Lock()
cb.state = HalfOpen
cb.mutex.Unlock()
} else {
return nil, ErrCircuitOpen
}
case HalfOpen:
// 只允许少量试探请求
}
result, err := req()
cb.mutex.Lock()
defer cb.mutex.Unlock()
if err != nil {
cb.failureCount++
if cb.failureCount >= cb.failureThreshold {
cb.state = Open
cb.lastFailure = time.Now()
}
} else {
if cb.state == HalfOpen {
cb.state = Closed
}
cb.failureCount = 0
}
return result, err
}
生产级实现要点
- 并发安全:所有状态变更必须使用读写锁保护
- 配置参数:
type Config struct {
FailureThreshold int // 触发熔断的失败次数
ResetTimeout time.Duration // 熔断恢复时间
WindowSize int // 统计窗口大小
MinRequests int // 最小请求数才开始统计
}
- 指标暴露:通过Prometheus metrics暴露熔断状态
- 动态配置:支持运行时调整阈值参数
集成示例
// 与HTTP客户端集成
func WithCircuitBreaker(client *http.Client, cb *CircuitBreaker) *http.Client {
client.Transport = &circuitBreakerTransport{
base: client.Transport,
cb: cb,
}
return client
}
type circuitBreakerTransport struct {
base http.RoundTripper
cb *CircuitBreaker
}
func (t *circuitBreakerTransport) RoundTrip(req *http.Request) (*http.Response, error) {
var resp *http.Response
err := t.cb.Execute(func() (interface{}, error) {
return t.base.RoundTrip(req)
})
if err != nil {
return nil, err
}
resp = err.(*http.Response)
return resp, nil
}
实际项目中推荐使用经过验证的库如sony/gobreaker或afex/hystrix-go,这些库提供了完整的熔断器实现和丰富的监控指标。



)