Skip to content

Latest commit

 

History

History
137 lines (103 loc) · 2.61 KB

File metadata and controls

137 lines (103 loc) · 2.61 KB

6.4 熔断降级

📍 导航返回目录 | 上一节:API网关 | 下一节:链路追踪


三种状态

  • Closed(闭合):正常请求
  • Open(打开):熔断,直接返回错误
  • Half-Open(半开):尝试恢复
Closed → (失败率>阈值) → Open
Open → (超时) → Half-Open  
Half-Open → (成功) → Closed
Half-Open → (失败) → Open

Go实现

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
}

本章小结

关键要点

  • ✅ 熔断防止雪崩
  • ✅ 三种状态自动切换
  • ✅ 降级保证可用性
  • ✅ 监控熔断指标

⏮️ 上一节:API网关 | ⏭️ 下一节:链路追踪