功能说明
示例实现三态熔断器。关闭状态下正常调用,连续失败达到阈值后进入打开状态,所有请求立即返回 ErrOpen,不再打到下游;冷却时间结束后,下一次调用把状态切到半开,允许一次探测,成功则回到关闭并清零失败计数,失败则重新打开并重置冷却计时。
关键代码
if b.state == StateOpen {
if b.now().Sub(b.openedAt) < b.cooldown {
return ErrOpen
}
b.state = StateHalfOpen
}
...
if err == nil {
b.state = StateClosed
b.failures = 0
return
}
b.failures++
if b.state == StateHalfOpen || b.failures >= b.threshold {
b.state = StateOpen
b.openedAt = b.now()
}
状态转换全部在锁内完成,避免并发调用看到中间的半开状态。
使用注意
- 半开状态没有限制并发探测数量,多个请求可能同时放行;严格场景应增加探测令牌。
- 冷却时间由注入的
now计算,示例用假时钟演示,生产默认time.Now。 - 成功调用会清零失败计数,因此偶发失败不会累积到阈值。
- 熔断只保护调用方,不负责重试;通常在打开时返回缓存或降级结果。
- 计数与状态在进程内,多实例需要共享指标或使用服务网格。
验证方式
示例前两次失败后阈值达到 2,第三次调用直接返回 circuit breaker is open;假时钟前进 150 毫秒后状态变为半开,探测成功回到关闭。把阈值改为 1 或把冷却时间调大,可验证不同分支。