Circuit Breaker 熔断器
ling-base common/circuitbreaker 模块文档
在线 Playground
在浏览器中直接体验本页相关 API,无需本地安装 Go 环境。
另见专题文档:熔断器完整文档。以下为
common/circuitbreaker包 README 全文。
circuitbreaker
A thread-safe circuit breaker with Closed / Open / Half-Open state machine, sliding-window failure-rate statistics, and configurable thresholds.
States
failure rate >= threshold recovery timeout
┌──────────────────────────┐ ┌─────────────────────┐
│ ▼ │ ▼
CLOSED ◄─────────────────── HALF-OPEN ◄───────────────── OPEN
▲ all trial requests succeed │ any trial request fails
└─────────────────────────────────┘- Closed: requests pass through. Failures are tracked in a sliding window. When the failure rate exceeds the threshold, the breaker trips to Open.
- Open: requests are rejected immediately with
ErrCircuitOpen. After the recovery timeout, the breaker transitions to Half-Open. - Half-Open: a limited number of trial requests are allowed. If all succeed, the breaker closes. If any fails, it re-opens.
Quick start
import "github.com/LingByte/ling-base/common/circuitbreaker"
cb := circuitbreaker.New(circuitbreaker.Config{
MaxRequests: 5, // trial requests in Half-Open
FailureThreshold: 0.5, // 50% failure rate trips the breaker
MinRequests: 10, // need at least 10 requests before evaluating
RecoveryTimeout: 30 * time.Second,
Name: "my-service",
OnStateChange: func(name string, from, to circuitbreaker.State) {
log.Printf("breaker %s: %s → %s", name, from, to)
},
})
err := cb.Execute(ctx, func(ctx context.Context) error {
return callRemoteService(ctx)
})
if errors.Is(err, circuitbreaker.ErrCircuitOpen) {
// fallback / return cached response
}Integration with retry
Combine circuit breaker with retry for resilient remote calls — retry handles transient failures within a single call, while the circuit breaker prevents cascading failures across calls:
err := cb.Execute(ctx, func(ctx context.Context) error {
return retry.Do(ctx, func(ctx context.Context) error {
return callRemote(ctx)
},
retry.WithMaxAttempts(3),
retry.WithExponentialBackoff(100*time.Millisecond, 5*time.Second, 2.0, true),
)
})Or use the retry.WithCircuitBreaker option:
err := retry.Do(ctx, op,
retry.WithMaxAttempts(3),
retry.WithCircuitBreaker(cb),
)When the breaker is open, the retry loop stops immediately with
ErrCircuitOpen — no further attempts are made.
Configuration
| Field | Description | Default |
|---|---|---|
MaxRequests | Trial requests allowed in Half-Open | 5 |
FailureThreshold | Failure rate (0.0–1.0) that trips the breaker | 0.5 |
MinRequests | Minimum requests before evaluating failure rate | 10 |
RecoveryTimeout | How long the breaker stays Open | 30s |
SlidingWindowSize | Number of recent outcomes in the window | 100 |
OnStateChange | Callback on state transitions | nil |
Name | Breaker identifier (for logs/metrics) | "" |
Metrics
m := cb.Metrics()
// m.State, m.WindowLen, m.Failures, m.Successes, m.FailureRate, m.GenerationLicense
MIT