hystrix-go简介
hystrix是一个容错库,旨在隔离指向远程系统,服务和第三方库的请求,杜绝级联故障,并在复杂的分布式系统中实现弹性,毕竟在分布式系统中,故障是不可避免的。
此项目脱胎于由Netflix开源的同名java项目。https://github.com/Netflix/Hystrix
像Hystrix命令一样执行代码
定义依赖于外部系统的应用逻辑,将函数传给Go
。当外部系统处于健康状态,这个函数将是唯一被执行的代码。
hystrix.Go("my_command", func() error {
// talk to other services
return nil
}, nil)
定义fallback行为
如果希望外部系统挂了的时候执行一些动作,可以给Go
传递第二个函数。理想情况下,这里的逻辑可以让你的应用优雅地处理外部系统不可用的情况。
当第一个函数返回error,或者在一系列健康检查的情况下函数无法运行结束,都会触发fallback。更详细的参考在这里
hystrix.Go("my_command", func() error {
// talk to other services
return nil
}, func(err error) error {
// do this when services are down
return nil
})
等待输出
调用Go
就像执行了一个goroutine,除了你能获取到一个error的channel并且监控它。
output := make(chan bool, 1)
errors := hystrix.Go("my_command", func() error {
// talk to other services
output <- true
return nil
}, nil)
select {
case out := <-output:
// success
case err := <-errors:
// failure
}
同步API
调用一个借口并且等待返回是一个常见的场景(对应于goroutine),Hystrix提供了一个Do
函数,返回一个error
err := hystrix.Do("my_command", func() error {
// talk to other services
return nil
}, nil)
配置
在应用启动期间,你可以调用ConfigureCommand
来为每个command添加配置:
hystrix.ConfigureCommand("my_command", hystrix.CommandConfig{
Timeout: 1000,
MaxConcurrentRequests: 100,
ErrorPercentThreshold: 25,
})
也有别的配置方法,更详细的介绍请参考官方文档。
一个例子
最后给大家举个例子
package main
import (
"fmt"
"github.com/afex/hystrix-go/hystrix"
"net/http"
"time"
)
func main() {
hystrix.Go("get_baidu", func() error {
// talk to other services
_, err := http.Get("https://www.baidu.com/")
if err != nil {
fmt.Println("get error")
return err
}
return nil
}, func(err error) error {
fmt.Println("get an error, handle it")
return nil
})
time.Sleep(2 * time.Second) // 调用Go方法就是起了一个goroutine,这里要sleep一下,不然看不到效果
}
网络请求,大家把网络断开后就能够模拟外部服务挂掉的情况。
总结
熔断机制在分布式系统中几乎是必备的组件,下面总结一下:
特点
-
hystrix作用在客户端,客户端程序依赖hystrix相关的第三方包,使得客户端与所依赖的服务,形成隔离(goroutine的隔离)。依赖服务的延迟与失败变的可控。保护调用者goroutine的执行。
-
避免了分布式系统中,单个组件的失败导致的级联影响。
-
快速失败,迅速恢复。 hystrix有快速失败机制,单个组件服务失败率到一定程度后,再请求,会直接响应失败。再这之后,会有重试机制。减少系统在错误服务调用上的开销。
-
降级应用
hystrix的设计原则
-
防止任何单个依赖服务耗尽所有用户线程
-
直接响应失败,而不是一直等待
-
提供错误返回接口,而不是让用户线程直接处理依赖服务抛出的异常
-
使用隔离或熔断技术来降低并限制单个依赖对整个系统造成的影响
相关文章
- 【Go命令教程】14. go env
- 【Go命令教程】10. go fix 与 go tool fix
- [Go] Http包 使用简介
- 五分钟学会使用 go modules(含在家办公使用技巧)
- [Go] using For loop as While loop
- 【Go语言】【8】GO语言的条件语句和选择语句
- Go netpoll I/O 多路复用构建原生网络模型之源码深度解析
- go-study
- golang gin数据绑定综合案例:用户注册及自定义数据校验器的应用:github.com/go-playground/validator/v10/translations/zh
- 解决go项目报错:fatal: could not read Username for ‘https://gitee.com‘: terminal prompts disabled
- go gin框架:PostFormArray接收数组类请求参数
- Go Gin使用html模板:访问html页面
- golang安装beego报错:go: cannot use path@version syntax in GOPATH mode
- 【GO】K8s 管理系统项目27[前端部分–Ingress]
- 【Go】go实现 — 冒泡排序算法
- 【Go资料】go语言学习资料书籍
- 【编程实践】用 go 语言实现 B+ 树
- Go语言并发与并行学习笔记(三)
- Go语言自学系列 | golang切片的初始化
- 387集Go语言核心编程培训视频教材整理 | 程序流程控制(一)
- 387集Go语言核心编程培训视频教材整理 | Golang变量(二)
- go 爬取页面保存
- Go语言笔记----goroutine和channel
- 【gRPC】第4篇 go语言实现gRPC(示例实践演示)
- Go 聚合类型 结构体 struct 定义 声明 初始化 嵌入
- Go struct 和 interface:结构体与接口都实现了哪些功能?
- Go 文件操作 文件打开和关闭 os.Open(name string)(*File,error) File.Close()