(微服务)服务治理:熔断器介绍以及hystrix-go的使用
一、什么是熔断器
要理解熔断器,可以先看看电路中使用的保险丝。
保险丝(fuse)也被称为电流保险丝,IEC127 标准将它定义为“熔断体(fuse-link)”。保险丝是一种保证电路安全运行的电子元器件,作用就是在电流异常升高到一定的高度和热度的时候,自身熔断切断电流,这样可以保护电路安全运行。
保险丝是一种自我保护装置,保护整个电路线路安全。保护整个电路线路安全是说一户家庭用户用电太高或异常保险丝烧断,只影响这家用户用电情况,不会影响线路上的其它家庭用电情况。

- 那微服务治理中的熔断器呢?
它也是一种保护装置,用来保护服务,在流量过高时,保护其它服务能安全运行。
在微服务架构中,系统是由很多服务组成的,一个服务功能可能依赖多个服务,如下简图,服务 C 依赖服务 E 和 服务 F,服务 B 也依赖服务 E。这还是一个小例子图。看看 Uber 的微服务依赖全图,依赖关系更加复杂,相互依赖关系密密麻麻。

当一个服务遇到访问异常流量时,影响的不仅是自身服务,还会影响到与之依赖的服务,依赖的服务又影响它依赖的服务,子子孙孙无穷匮,这样有可能引起系统崩溃,这就是雪崩效应。
要怎么办?
可以使用熔断器为微服务调用提供保护机制。熔断器像“保险丝”一样,它作为一个开关,遇到异常流量,可以打开熔断器断开服务;服务恢复后,又可以关闭熔断器,重新调用服务。
- 服务治理中熔断器:
服务熔断是指调用方访问服务时,通过熔断器做代理来进行访问,熔断器会持续观察服务返回的成功、失败的状态,当失败次数超过设置的阙值时,熔断器断开,请求就不能访问到下游服务了。

它的作用:1. 当所依赖的服务不稳定时,能够起到快速失败的目的
2. 快速失败后,能够用一定的算法动态探测所依赖对象是否恢复
二、熔断器的3种状态
熔断器实现主要是设置一个阙值,这个阙值可以是最大并发数,请求错误率百分比等,超过这个阙值就进行熔断。还会设置一个尝试恢复时间。
熔断器有3种状态:
- CLOSED:默认状态。熔断器计算数(最大请求数、请求错误百分比等)没有达到设置的阙值,熔断器就认为被代理服务状态良好。
- OPEN:熔断器计算数计算数(最大请求数、请求错误百分比等)已经达到阙值,熔断器就认为被代理的服务已经故障了,打开熔断器开关,请求不再代理服务,而是快速失败。
- HALF OPEN:熔断器打开后,为了能自动恢复被代理服务的访问,会切换到半开放状态,去尝试请求被代理服务以查看服务故障是否已经恢复了。如果恢复了,会转为 CLOSED 状态;否则转到 OPEN 状态。

熔断器需要考虑的一些问题:
- 熔断时长的设置,超过这个时长后切换到 HALF OPEN 进行重试。
- 重试时,要注意业务是否允许这样做。
- 不同的异常,需要定义熔断后不同处理逻辑。
- 记录请求失败日志,供以后人工处理使用。
三、熔断框架 hystrix-go
hystrix-go 介绍
hystrix-go 是一个用 Go 语言开发的熔断框架。
hystrix-go 是一个延迟和容错的库,作用是隔离系统调用、服务和第三方调用等,阻止级联故障,并在故障不可避免的复杂分布式系统中能够实现恢复的能力。它是基于 Netflix 的同名项目:https://github.com/Netflix/Hystrix 。
可以看看 Netflix 的 Hystrix 是如何工作,对了解 hystrix-go 有很大帮助,https://github.com/Netflix/Hystrix/wiki/How-it-Works :
- Construct a
HystrixCommandorHystrixObservableCommandObject- Execute the Command
- Is the Response Cached?
- Is the Circuit Open?
- Is the Thread Pool/Queue/Semaphore Full?
HystrixObservableCommand.construct()orHystrixCommand.run()- Calculate Circuit Health
- Get the Fallback
- Return the Successful Response
使用方法介绍
hystrix-go 的调用方法有 2 个:
- Do:同步调用
func Do(name string, run runFunc, fallback fallbackFunc)
- Go:异步调用
func Go(name string, run runFunc, fallback fallbackFunc)
- 将代码作为 hystrix-go 的命令执行
hystrix.Go("my_command", func() error {
// talk to other services
return nil
}, nil)
定义一个依赖外部系统的应用程序逻辑,然后将这个函数传递给 Go。当系统没有问题时,将会执行这个程序逻辑。
- 定义失败后执行的业务逻辑
hystrix.Go("my_command", func() error {
// talk to other services
return nil
}, func(err error) error {
// do this when services are down,调用服务失败后,可以在这里执行一些逻辑
return nil
})
如果想在服务中断期间执行一些业务逻辑,可以传入第三个参数,这个参数也是一个匿名函数。这第三个参数作用就是在第二个参数(匿名函数)的代码调用服务返回错误时,执行的一些业务逻辑。
hystrix.Go(
"my_command",
func() error {
// talk to other services
_, err := http.Get("https://google.com")
if err != nil {
fmt.Println("Get baidu err: %v", err)
return err
}
return nil
},
func(err error) error {
// do this when services are down
fmt.Println("上面匿名函数中代码调用服务错误时,运行这里的代码")
return nil
},
)
- 等待输出
可以选择监控的输出,如下:
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
}
- 配置设置
func Configure(cmds map[string]CommandConfig)
func ConfigureCommand(name string, config CommandConfig)
Configure 方法内部也是调用的 ConfigureCommand 方法。
hystrix-go 有一个默认配置。
也可以设置配置,如下:
hystrix.ConfigureCommand(
"my_command", // 熔断器的名字,一个名字对应一个熔断器
hystrix.CommandConfig{
Timeout: 1000, //超时时间,单位毫秒 ms。默认 1000ms
MaxConcurrentRequests: 100, // 最大并发数,超过这个设置就返回错误。默认 10
ErrorPercentThreshold: 25, // 设置错误数量统计百分比阙值,超过这个阙值,就开启熔断。默认 50
RequestVolumeThreshold: 4, // 一个窗口10秒内请求的数量阙值,达到这个阙值就开启熔断
SleepWindow: 1000, // 熔断器被激活后,多久重试服务是否可用,单位毫秒。默认 5000ms
})
- RequestVolumeThreshold:一个窗口10秒内请求的数量阙值,判断熔断开关的条件之一。请求数量大于等于这个设置的数量阙值后,且错误百分比也达到设置的阙值,就开启熔断
- ErrorPercentThreshold:错误数量统计百分比阙值,判断熔断开关的条件之一。请求数量大于等于 RequestVolumeThreshold 并且错误百分比达到这个百分比后就会开启熔断
- 在dashboard中显示hystrix上报信息
main.go 程序中,在 http 的一个端口上注册一个事件流并且在 goroutine 中启动它,就可以在这个http端口上查看这个上报流。如果你在 Hystrix Dashboard 配置了这个事件流,那么事件信息就可以自动显示在 dashboard 上。
hystrixStreamHandler := hystrix.NewStreamHandler()
hystrixStreamHandler.Start()
go http.ListenAndServe(net.JoinHostPort("", "81"), hystrixStreamHandler)
上面的代码开启了 dashboard,在 http 端口 81 上可以查看 hystrix 上报的信息,http://localhost:81。
- 可以向 Statsd 发送 circuit metric
c, err := plugins.InitializeStatsdCollector(&plugins.StatsdCollectorConfig{
StatsdAddr: "localhost:8125",
Prefix: "myapp.hystrix",
})
if err != nil {
log.Fatalf("could not initialize statsd client: %v", err)
}
metricCollector.Registry.Register(c.NewStatsdCollector)
代码示例
一个简单使用 hystrix-go 示例代码:
package main
import (
"fmt"
"net/http"
"github.com/afex/hystrix-go/hystrix"
)
func main() {
hystrix.ConfigureCommand("my_command_name", hystrix.CommandConfig{
Timeout: 1000, // 超时时间1000ms
MaxConcurrentRequests: 40, // 最大并发数40
RequestVolumeThreshold: 20, // 请求数量阙值20,达到这个阙值才可能触发熔断
ErrorPercentThreshold: 20, // 错误百分比例阙值 20%
})
client := http.Client{}
doRequest := func() error {
req, err := http.NewRequest("GET", "https://www.bin.com", nil)
if err != nil {
return err
}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
fmt.Println("doRequest: ", resp.Status)
return nil
}
err := hystrix.Do("my_command_name", func() error {
return doRequest()
}, nil)
if err != nil {
fmt.Println("end: ", err)
}
}
创建一个 http 客户端,封装一个 doRequest 请求函数。
然后调用 hystrix.Do 函数,把封装好的 doRequest 函数放在 Do 函数的第二个参数中执行,Do 函数会监视请求的执行情况,会根据超时时间、并发数、错误百分比阙值等来判断是否允许请求执行,当达到某个阙值时,将会触发熔断器,并执行熔断器的错误执行逻辑,也就是 Do 函数第三个参数,在这段代码中直接设置为 nil ,没有编写错误逻辑代码,也就不执行。
也可以到我的公众号 九卷技术录:(微服务)服务治理:熔断器介绍以及hystrix-go的使用 继续讨论
四、参考
(微服务)服务治理:熔断器介绍以及hystrix-go的使用的更多相关文章
- Spring Cloud 微服务四:熔断器Spring cloud hystrix
前言:在微服务架构中,一般都是进程间通信,有可能调用链都比较长,当有底层某服务出现问题时,比如宕机,会导致调用方的服务失败,这样就会发生一连串的反映,造成系统资源被阻塞,最终可能造成雪崩.在sprin ...
- 分布式服务防雪崩熔断器(Hystrix),实现服务降级
Hystrix是什么? hystrix对应的中文名字是“豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,这与hystrix本身的功能不谋而合,因此Netflix团队将该框架命名 ...
- 分布式服务防雪崩熔断器,Hystrix理论+实战。
Hystrix是什么? hystrix对应的中文名字是"豪猪",豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,这与hystrix本身的功能不谋而合,因此Netfl ...
- .Net微服务实践(五)[服务发现]:Consul介绍和环境搭建
目录 介绍 服务发现 健康检查.键值存储和数据中心 架构 Consul模式 环境安装 HTTP API 和Command CLI 示例API介绍 最后 在上篇.Net微服务实践(四)[网关]:Ocel ...
- 基于.NET CORE微服务框架 -surging的介绍和简单示例 (开源)
一.前言 至今为止编程开发已经11个年头,从 VB6.0,ASP时代到ASP.NET再到MVC, 从中见证了.NET技术发展,从无畏无知的懵懂少年,到现在的中年大叔,从中的酸甜苦辣也只有本人自知.随着 ...
- springcloud微服务实战:Eureka+Zuul+Feign/Ribbon+Hystrix Turbine+SpringConfig+sleuth+zipkin
相信现在已经有很多小伙伴已经或者准备使用springcloud微服务了,接下来为大家搭建一个微服务框架,后期可以自己进行扩展.会提供一个小案例: 服务提供者和服务消费者 ,消费者会调用提供者的服务,新 ...
- 微服务:Eureka+Zuul+Ribbon+Feign+Hystrix构建微服务架构
原文地址:http://blog.csdn.net/qq_18675693/article/details/53282031 本案例将打架一个微服务框架,参考来源官方参考文档 微服务:是什么?网上有一 ...
- [转帖]微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务
微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务 http://skaka.me/blog/2016/04/21/springcloud1/ APR 21ST, ...
- 第五章 服务容错保护:Spring Cloud Hystrix
在微服务架构中,我们将系统拆分为很多个服务,各个服务之间通过注册与订阅的方式相互依赖,由于各个服务都是在各自的进程中运行,就有可能由于网络原因或者服务自身的问题导致调用故障或延迟,随着服务的积压,可能 ...
- 三、安装cmake,安装resin ,tars服务,mysql 安装介绍,安装jdk,安装maven,c++ 开发环境安装
三.安装cmake,安装resin 2018年07月01日 21:32:05 youz1976 阅读数:308 开发环境说明: centos7.2 ,最低配置:1核cpu,2G内存,1M带宽 1. ...
随机推荐
- [转帖]xsos:一个在 Linux 上阅读 SOSReport 的工具
https://www.sohu.com/a/315931829_100034897 xsos 是一个帮助用户轻松读取 Linux 系统上的 sosreport 的工具.另一方面,我们可以说它是 so ...
- [转帖]简单理解Linux的Memory Overcommit
https://zhuanlan.zhihu.com/p/551677956 Memory Overcommit的意思是操作系统承诺给进程的内存大小超过了实际可用的内存.一个保守的操作系统不会允许me ...
- [转帖]⭐万字长篇超详细的图解Tomcat中间件方方面面储备知识⭐
https://developer.aliyun.com/article/885079?spm=a2c6h.24874632.expert-profile.321.7c46cfe9h5DxWK 202 ...
- 庖丁解牛:最全babel-plugin-import源码详解
庖丁解牛:最全 babel-plugin-import 源码详解 序言:在用 babel-plugin 实现按需加载一文中笔者用作用域链思路实现了按需加载组件.此思路是统一式处理,进入 ImportD ...
- FinClip 小程序的自有账户体系是怎么做的?
随着公司规模越来越大,员工需要使用的产品矩阵也会越来越丰富,不仅包括内部的 IT 系统,OA 系统,业务系统,还会有很多和外部产品集成的登录流程,更别提各种业务系统或者子系统中的账户体系了.如果使用简 ...
- Python获取内存、CPU利用率,CPU温度
最近一个项目的需求,在软件上加入硬件实时信息,大概搜索一下,没太好的结果,所以决定自己写一篇 我的代码不难发现,都使用了psutil包,为什么呢,别的包我没太关注,纯粹是这台机的环境上有这个包 如果大 ...
- 自动化部署实例(donetcore GitLab CICD )
主要简单的介绍了一下 GitLab CI 的持续集成以及持续部署,这篇将通过 GitLab CI 发布一个 .net core 项目,来带小伙伴们感受一下自动化的魅力,从此告别手动发布. 准备工作 创 ...
- python入门之后须掌握的知识点(模块化编程、时间模块)【一】
相关文章: 全网最详细超长python学习笔记.14章节知识点很全面十分详细,快速入门,只用看这一篇你就学会了! python入门合集: python快速入门[一]-----基础语法 python快速 ...
- 11.1 C++ STL 应用字典与列表
C++ STL 标准模板库提供了丰富的容器和算法,这些模板可以灵活组合使用,以满足不同场景下的需求.本章内容将对前面学习的知识进行总结,并重点讲解如何灵活使用STL中的vector和map容器,以及如 ...
- Eslint 的rules一些配置 (.eslintrc.js文件中的rules选项)
rules: { // off=0, warn=1, error=2, 如果是数组, 第二项表示参数option // indent: [2, 2], // 控制缩进为2 eqeqeq: 1, // ...