content/articles/sony-gobreaker/README.md
最近看了一下go-kit,发现这个微服务框架的熔断器,也是使用sony开源的作为基础。 sony开源在 github 的熔断器 在源代头注释中发现,原来sony实现的是微软2015时公布的CircuitBreaker标准,果然微软才开源界的大神。
微软的原文件在此:https://msdn.microsoft.com/en-us/library/dn589784.aspx 名不知道怎么正确翻译,直观翻译,可能叫:环形熔断器(或叫:循环状态自动切换中断器)。 因为它是在下面3个状态循环切换 :
Closed
/ \
Half-Open <--> Open
初始状态是:Closed,指熔断器放行所有请求。
达到一定数量的错误计数,进入Open 状态,指熔断发生,下游出现错误,不能再放行请求。
经过一段Interval时间后,自动进入Half-Open状态,然后开始尝试对成功请求计数。
进入Half-Open后,根据成功/失败计数情况,会自动进入Closed或Open。
// 从定义的错误来看,sony的应该增加了对连接数进行了限制 。
var (
// ErrTooManyRequests is returned when the CB state is half open and the requests count is over the cb maxRequests
ErrTooManyRequests = errors.New("too many requests")
// ErrOpenState is returned when the CB state is open
ErrOpenState = errors.New("circuit breaker is open")
)
type Settings struct {
Name string
MaxRequests uint32 // 半开状态期最大允许放行请求:即进入Half-Open状态时,一个时间周期内允许最大同时请求数(如果还达不到切回closed状态条件,则不能再放行请求)。
Interval time.Duration // closed状态时,重置计数的时间周期;如果配为0,切入Open后永不切回Closed--有点暴力。
Timeout time.Duration // 进入Open状态后,多长时间会自动切成 Half-open,默认60s,不能配为0。
// ReadyToTrip回调函数:进入Open状态的条件,比如默认是连接5次出错,即进入Open状态,即可对熔断条件进行配置。在fail计数发生后,回调一次。
ReadyToTrip func(counts Counts) bool
// 状态切换时的熔断器
OnStateChange func(name string, from State, to State)
}
要把熔断器使用到工程中,只需要,实例化一个gobreaker,再使用这个Execute包一下原来的请求函数。
func (cb *CircuitBreaker) Execute(req func() (interface{}, error)) (interface{}, error) {
generation, err := cb.beforeRequest() //
if err != nil {
return nil, err
}
defer func() {
e := recover()
if e != nil {
cb.afterRequest(generation, false)
panic(e) // 如果代码发生了panic,继续panic给上层调用者去recover。
}
}()
result, err := req()
cb.afterRequest(generation, err == nil)
return result, err
}
函数做了几件事: