发布时间:2025-11-05 01:28:14 来源:云智核 作者:IT科技
一些场景下,实现为了保障服务稳定性会引入熔断机制。熔断本文介绍了用 Go 语言自己实现熔断需要什么操作。机制

熔断是指在下游发生错误时上游主动关闭或限制对下游的请求。

总得来说三个状态的转换大致如下图:

https://github.com/rubyist/circuitbreaker
CLOSE 允许
OPEN
在 CoolingTimeout 冷却时间内,熔断不允许 过了冷却时间,机制状态变为 HALFOPEN,允许访问HALFOPEN
在 DetectTimeout 检测时间内,允许访问 否则不允许atomic.StoreInt32((*int32)(&b.state), int32(HALFOPEN))
window 实现类
type window struct { sync.RWMutex oldest int32 // oldest bucket index latest int32 // latest bucket index buckets []bucket // buckets this window holds bucketTime time.Duration // time each bucket holds bucketNums int32 // the numbe of buckets inWindow int32 // the number of buckets in the window allSuccess int64 allFailure int64 allTimeout int64 conseErr int64 } type bucket struct { failure int64 success int64 timeout int64 }用环形队列实现动态统计。把一个连续的时间切成多个小份,每一个 bucket 保存 BucketTime 的统计数据,BucketTime * BucketNums 是统计的时间区间。
每 BucketTime,会有一个 bucket 过期
if w.inWindow == w.bucketNums { // the lastest covered the oldest(latest == oldest) oldBucket := &w.buckets[w.oldest] atomic.AddInt64(&w.allSuccess, -oldBucket.Successes()) atomic.AddInt64(&w.allFailure, -oldBucket.Failures()) atomic.AddInt64(&w.allTimeout, -oldBucket.Timeouts()) w.oldest++ if w.oldest >= w.bucketNums { w.oldest = 0 } } else { w.inWindow++ } w.latest++ if w.latest >= w.bucketNums { w.latest = 0 } (&w.buckets[w.latest]).Reset()