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执行失败
状态转换
- 三种状态
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