熔断器-hystrix-go

155 阅读3分钟

hystrix-go

参考链接

服务雪崩

服务雪崩效应是一种因 服务提供者不可用导致,服务的调用者 也不可用,并将不可用的范围 逐渐放大的,最终导致整个系统不可用的情况, 这种现象就叫做,雪崩效用,

为了解决微服务雪崩效应,提出来使用熔断机制为微服务链路提供保护机制。(CircuitBreaker)

当链路的中某个【微服务】不可用(无法链接,响应超时,等等错误),会进行服务的降级,熔断该节点 与 依赖微服务节点的调用,

快速返回错误响应信息,当检测到该节点 微服务调用响应正常后,恢复调用链路

熔断器hystrix-go

是什么

基于java的的 hystrix的 实现的 go版本的 熔断器

对不满足hystrix(指定配置规则)的请求,提前结束请求。减少服务器链接资源。

提前结束请求:

当发现服务端有大量的报错,则【熔断器】会根据配置来决定是否要开启,从而拒绝客户端请求,比例大量请求占用资源不释放,导致服务端不可用。

当服务端恢复正常是,根据【SleepWindows】时间间隔,检查服务是否可用。来关闭熔断器

功能

  • 限流
  • 超时
  • 基于滑动窗口的metric指标统计(每次get都会删除小于10s的数据 map[sec]numberBucket)
  • metric的WebUI界面
  • 支持异步和同步执行

缺点

  • 代码过于复杂
  • 业务发生painc,没有做 recover处理
  • 好像已经停止维护
  • 每执行一个 业务处理函数,都会启动2个goroutine
  • 对外暴露的可用信息少,(此时状态转移的信息)
  • 一刀切在处于 StateOpen状态下,会拒绝所有的请求,在指定的时间段
  • stateHalfOpen状态下,允许通过的请求数量没有做特殊的限制。 (MaxConcurrentRequests 最大并发数,服务正常时候可以用它,当服务不正常是用它就不太合适)

配置讲解

type CommandConfig struct {
	Timeout                int `json:"timeout"`
	MaxConcurrentRequests  int `json:"max_concurrent_requests"`
	RequestVolumeThreshold int `json:"request_volume_threshold"`
	SleepWindow            int `json:"sleep_window"`
	ErrorPercentThreshold  int `json:"error_percent_threshold"`
}


// 默认值
var(
	DefaultTimeout = 1000
	// DefaultMaxConcurrent is how many commands of the same type can run at the same time
	DefaultMaxConcurrent = 10
	// DefaultVolumeThreshold is the minimum number of requests needed before a circuit can be tripped due to health
	DefaultVolumeThreshold = 20
	// DefaultSleepWindow is how long, in milliseconds, to wait after a circuit opens before testing for recovery
	DefaultSleepWindow = 5000
	// DefaultErrorPercentThreshold causes circuits to open once the rolling measure of errors exceeds this percent of requests
	DefaultErrorPercentThreshold = 50
)
  • Timeout(单位ms,默认1000ms,)

请求超时时机,内部会基于 Timer创建一个计时器,

  • MaxConcurrentRequests(默认10)

同一个时间并发请求数的限制,内部会创建一个 p.Tickets = make(chan *struct{}, p.Max) 大小的一个令牌桶,用来做请求限流

  • RequestVolumeThreshold(默认20)

10s内请求数量的阀值,熔断器触发条件之一,如果大于该阀值,则会在判断【10s错误百分比】是否大于阀值

  • SleepWindow(单位ms,默认5000)

由 stateOpen ——》staeHalfOpen 的睡眠窗口,在该期间会 尝试 放量请求来检测服务是否可用。

  • ErrorPercentThreshold(默认 50)

10s内错误百分比的阀值,熔断器触发条件之一 int((10sErrors / 10sReqs)*100 + 0.5) < ErrorPercentThreshold 不满足则触发。

+0.5是 防止四舍五入少了, 比如29.9,避免变为29,

fallback的执行时机

发送错误就执行 fallback函数

  • 请求条件不满足
  • 获取不到令牌桶
  • 执行command失败
  • 超时
  • ctx.Done
  • fallback执行失败

状态转换

hystrix-go-熔断器状态转换.png

  • 三种状态

StateClosed:允许服务正常访问

StateOpen:拒绝服务请求

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

  • 四种状态切换

【1】StateClosed->StateOpen:

10s错误的百分比 < 配置ErrorPercentThreshold,则设置状态为 StateOpen

【2】StateOpen->StateHalfOpen:

当前时间 > 最后一次熔断时间+SleepWindow,则状态为 StateHalfOpen

【3】StateHalfOpen->StateClosed:

只要有一个 req执行成功,则将状态设置 StateClosed

	if eventTypes[0] == "success" && o {circuit.setClose()}

【4】StateHalfOpen->StateOpen:

!(当前时间 > 最后一次熔断时间+SleepWindow) 则表示状态为 StateOpen