熔断器-gobreaker

463 阅读3分钟

gobreaker

参考链接

熔断器gobreaker

是什么

是基于微软云 设计模式 断路器 设计的golang实现,代码简易通俗易懂

github地址-gobreaker

功能

  • 对外提供钩子函数,(ReadyToTrip,OnStateChange,IsSuccessful)
  • HalfOpen期间,可以设置允许执行的最大请求数,避免在服务本身不可用的情况下还有大量的请求去尝试连接服务端占用资源
  • 业务执行是否成功的 IsSuccessful的可以自定义判断标准
  • 允许对外暴露 metric的信息,
  • OnStateChange,实现钩子函数,能够实时 监听 状态发生的变化信息

缺点

  • 不支持 超时(Execute)执行的超时时间
  • 只有同步执行,
  • 没有提供 metric 的WebUI界面
  • 一刀切在处于 StateOpen状态下,会拒绝所有的请求,在指定的时间段

配置参数详解

type Settings struct {
	Name          string
	MaxRequests   uint32 //     half-open下 允许的最多的并发数,如果为0则表示值允许1个,
	Interval      time.Duration // 在熔断器关闭的状态下,满足这个周期则清除counts,如果为0则不清除counts
	Timeout       time.Duration  // 在熔断器处于 open 状态下,满足这个周期,则设置为 half-open 默认值50s
	ReadyToTrip   func(counts Counts) bool // 失败并且处于关闭状态下,readyToTrip返回True,则设置为打开状态,readyToTrip为nil则使用默认机制【连续失败次数 >5 则返回返回True】
	OnStateChange func(name string, from State, to State) // 每当状态发生改变是都会调用
	IsSuccessful  func(err error) bool // req函数执行后,根据  req返回的err,来执行 IsSuccessful 是否执行成功
}
  • Name

circuit的名称

  • MaxRequests

默认值1,

0、当熔断器处于 half-open状态下时,允许最多的并发数

0、当有 StateHalfOpen->StateClosed是, 需要满足 cb.counts.ConsecutiveSuccesses >= cb.maxRequests 条件,才可以转为 StateClosed

  • Interval

StateClosed 状态下,满足这个周期则清除counts,并重新设置周期,如果为0则不清除counts

默认值为0,

其一:这样做的原因是(counts的值总不能一直累计,万一超出类型范围呢?所以要想办法在一定的时间段在重新重置)

其二:不做无用功,本来就是正常的,一直统计页没有什么意义。

  • Timeout

StateOpen的状态的 持续的超时时间,如果满足超时时间了,则设置状态为 StateHalfOpen

默认TimeOut为:60s

  • ReadyToTrip(func)

onFailure:

StateClosed状态下,ReadyToTrip执行函数返回True则 StateClosed->StatedOpen,

ReadToTroip默认,失败的次数超过5次,则返回True

  • OnStateChange(func)

每次状态发生方便,都会调用该 钩子状态函数

  • IsSuccessful(func)

对要执行的请求函数返回的err判断,

默认值,针对非 nil的err都返回False,

Count结构详解

type Counts struct {
	Requests             uint32
	TotalSuccesses       uint32
	TotalFailures        uint32
	ConsecutiveSuccesses uint32 // 连续执行成功的次数,有一次执行失败,该值就会被置为0
	ConsecutiveFailures  uint32 // 连续执行失败次数,有一次执行成功,该值就会被置为0
}
  • Requests

beforeRequest执行成功,则增加 Requests

  • onSuccess
func (c *Counts) onSuccess() {
	c.TotalSuccesses++
	c.ConsecutiveSuccesses++
	c.ConsecutiveFailures = 0
}
  • 运行函数执行失败
func (c *Counts) onFailure() {
	c.TotalFailures++
	c.ConsecutiveFailures++
	c.ConsecutiveSuccesses = 0
}

清除Count时机

  • StateClosed状态下面 满足 Interval时间,则toNewGeneration(now)
  • NewCircuitBreaker,时候toNewGeneration(now)
  • 设置新状态的时候setState,toNewGeneration(now)

状态转换

gobreader-熔断器状态转换.png

  • 三种状态

StateClosed:允许服务正常访问

StateOpen:拒绝服务请求

StateHalfOpen:允许通过部分请求,校验服务是否可用

  • 四种状态切换

【1】StateClosed->StateOpen:

运行函数执行失败或者panic,满足 readyToTrip 函数返回true则,设置状态为 StateOpen,

readyToTrip默认判断是,连续失败次数 > 5则返回true

if cb.readyToTrip(cb.counts) { cb.setState(StateOpen, now)}

【2】StateOpen->StateHalfOpen:

StateOpen的Timeout-expire,过期了,则设置状态为 StaeHalfOpen

TimeOut的默认过期是 60s

if cb.expiry.Before(now) {cb.setState(StateHalfOpen, now)}

【3】StateHalfOpen->StateClosed:

当连续成功的数量 > MaxRequest数量时,则设置状态为 StateClosed

if cb.counts.ConsecutiveSuccesses >= cb.maxRequests {cb.setState(StateClosed, now)}

【4】StateHalfOpen->StateOpen:

运行函数执行失败或者panic,则设置状态为 StateOpen

func (cb *CircuitBreaker) onFailure(state State, now time.Time) {
	switch state {
	case StateClosed:
	case StateHalfOpen:
		cb.setState(StateOpen, now)
	}
}