Hystrix是如何工作的
接上一篇:《Hystrix介绍》
流程图
下面这幅图相当重要

稍微解释一下上面的流程:
- Construct a HystrixCommand or HystrixObservableCommand Object
- Execute the Command
- Is the Response Cached?
- Is the Circuit Open?
- Is the Thread Pool/Queue/Semaphore Full?
- HystrixObservableCommand.construct() or HystrixCommand.run()
- Calculate Circuit Health
- Get the Fallback
- Return the Successful Response
1. 构造一个HystrixCommand或者HystrixObservableCommand对象
第一步是构造一个HystrixCommand或HystrixObservableCommand对象来表示对依赖项的请求。例如:
HystrixCommand command = new HystrixCommand(arg1, arg2);
HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);
2. 执行命令
你可以用下列四种中的任意一种方式执行命令:
- execute() — 阻塞,直到收到响应或者抛出异常.
- queue() — 返回一个Future
- observe() — 订阅代表响应的Observable
- toObservable() — 返回一个Observable,当你订阅它以后,将会执行Hystrix命令并且推送它的响应

execute()方法是同步执行的,它是调用queue().get()
queue()方法是异步执行的,它调用的是toObservable().toBlocking().toFuture()
所以最终每个HystrixCommand都是一个Observable的实现
3. 响应是否已经被缓存?
如果请求在缓存中可用,并且该请求对应的响应在缓存中也是可用的,那么缓存的这个响应将立即以一个Observable的形式被返回
4. 断路器是否打开?
当你执行命令的时候,Hystrix检查断路器是否是开着的。如果是开着的,那么Hystrix不会执行命令,而是路由到第8步执行回退逻辑。如果是关着的,将执行第5步,继续检查容量是否可用。
5. 线程池/队列/信号量是否已经满了?
如果这个命令所关联的线程池和队列(或者信号量)是否满了,如果是,那么Hystrix不会执行命令,而是立即路由到第8不执行回退逻辑
6. HystrixObservableCommand.construct() or HystrixCommand.run()
我们知道对依赖的调用请求都是封装成HystrixCommand或者HystrixObservableCommand执行的,而真正执行的逻辑是写在HystrixObservableCommand.construct()或者HystrixCommand.run()中的:
- HystrixCommand.run() — 返回一个响应或者抛出一个异常
- HystrixObservableCommand.construct() — 返回一个Observable,并且推送响应或者发送一个onError通知
如果在执行run()或者construct()方法超时,那么线程将抛出一个TimeoutException。
7. 计算电路健康
Hystrix报告成功、失败、拒绝、超时给断路器,断路器维护一组计算统计的计数器。
断路器用这些统计数据来决定什么时候应该“跳闸”,此时后续所有的请求都会被短路,直到一个恢复周期耗尽以后在第一次检查某些健康检查之后才会打开电路。
(PS:想象一下生活中的漏电保护器,电压过高时会自动跳闸,跳闸以后就没电了,家用电器都用不了了,之后你可以自己不去合上,当然前提是你不能再用那些大功率电器了,于是来电了)
8. 回退
当命令执行失败时,Hystrix试图恢复到您的fallback:当run()或者construct()抛出异常;当由于断路器跳闸导致命令被短路;当命令的线程池或队列容量满了;或者当命令执行超时。
在HystrixCommand的情况下,为了提供回退逻辑,你可以实现HystrixCommand.getfallback(),它返回一个单一的回退值。
对于HystrixObservableCommand(),为了提供回退逻辑,你需要实现hystrixobservablecomman.resumewithfallback(),它会返回一个Observable,这个Observable可能返回一个回退值或者多个值。
如果你没有实现一个fallback方法,或者fallback它自己抛了一个异常,此时Hystrix仍然会返回一个Observable,但是这个Observable什么都不会推送并立即发送一个onError通知。通过这个onError通知,造成命令失败的异常会传回给调用者。
9. 返回成功响应
如果Hystrix命令成功,它会返回响应给调用者,或者返回一个Observable。这取决于在第2步的时候你是如果调用命令的。
Circuit Breaker(断路器)
下图显示了HystrixCommand或HystrixObservableCommand是如何与HystrixCircuitBreaker交互的,以及它的逻辑和决策流程,包括断路器中计数器的行为。

上面的流程可以这样描述:
- 假设整个电路的体积达到一定的阈值
- 假设错误百分比超过设定的错误百分比阈值
- 断路器从CLOSED变成OPEN
- 当它打开时,经过这个断路器的所有请求被短路
- 过了一段时间以后,下一个单个请求被允许通过(此时是半打开状态)。如果这个请求失败,在接下来的睡眠窗口期间断路器保持OPEN状态;如果这个请求成功,断路器转成CLOSED状态;然后继续执行第1步,如此反复。
隔离
Hystrix使用隔板模式来隔离彼此的依赖关系,并限制对其中任何一个的并发访问。

线程和线程池
Hystrix使用独立的、每个依赖项的线程池作为约束任何给定依赖项的一种方式,因此底层执行的延迟只会使该池中的可用线程饱和。

线程池的好处
- 应用程序被完全保护而不受失控的客户端的影响。给定的依赖项的线程池可以填满,而不会影响应用程序的其余部分。
- 应用程序可以接收新的客户端请求
- 当失败的客户端再次恢复正常时,线程池将被清理,应用程序将立即恢复正常的性能
- 如果一个客户端配置错误,线程池的健康将会很快地证明这一点(通过增加错误、延迟、超时、拒绝等),并且您可以处理它(通常是通过动态属性进行实时处理),而不会影响应用程序的功能。
Semaphores(信号量)
你可以用信号量(或者计数器)来限制对任意依赖项并发调用的数量,代替用线程池的大小。
HystrixCommand 和 HystrixObservableCommand 在两个地方支持用信号量:
- Fallback:当Hystrix恢复fallbacks时它总是调用Tomcat的线程这样做
- Execution:如果设置属性execution.isolation.strategy为SEMAPHORE,那么,Hystrix将使用信号量而不是线程来限制调用该命令的发父线程的并数量。
https://github.com/Netflix/Hystrix/wiki/How-it-Works
Hystrix是如何工作的的更多相关文章
- hystrix文档翻译之工作原理
流程图 下面的图片显示了一个请求在hystrix中的流程图. 1.构造一个HystrixCommand或者HystrixObservableCommand对象 第一步是创建一个HystrixComma ...
- 从源码分析Hystrix工作机制
一.Hystrix解决了什么问题? 在复杂的分布式应用中有着许多的依赖,各个依赖都有难免在某个时刻失败,如果应用不隔离各个依赖,降低外部的风险,那容易拖垮整个应用. 举个电商场景中常见的例子,比如订单 ...
- springcloud之hystrix熔断器-Finchley.SR2版
本篇和大家分享的是springcloud-hystrix熔断器,其主要功能是对某模块调用失败做断路和降级,简单点就当某个模块程序出问题了并达到某阈值就限制后面请求,并降级的方式提供一个默认返回数据.最 ...
- Hystrix针对不可用服务的保护机制以及引入缓存
之前我写过一篇博文,通过案例了解Hystrix的各种基本使用方式,在这篇文章里,我们是通过Hystrix调用正常工作的服务,也就是说,Hytrix的保护机制并没有起作用,这里我们将在HystrixPr ...
- SpringCloud中使用Hystrix
1. 引言 一般而言,一个服务都是部署了多台机器的,那么在这种情况下,当其中一个服务挂了以后Hystrix是怎么处理的呢? 为了验证这个问题,我们准备两个服务:user-api 和 app-gate ...
- Spring Boot 集成 Hystrix
续: <Hystrix介绍> <Hystrix是如何工作的> <SpringCloud学习笔记(3)——Hystrix> Hystrix使用 package com ...
- Hystrix 配置参数全解析
code[class*="language-"], pre[class*="language-"] { background-color: #fdfdfd; - ...
- SpringCloud (十) Hystrix Dashboard单体监控、集群监控、与消息代理结合
一.前言 Dashboard又称为仪表盘,是用来监控项目的执行情况的,本文旨在Dashboard的使用 分别为单体监控.集群监控.与消息代理结合. 代码请戳我的github 二.快速入门 新建一个Sp ...
- 使用Hystrix进行微服务降级管理
前言:目前我们的项目是微服务架构,基于dubbo框架,服务之间的调用是通过rpc调用的.刚开始没有任何问题,项目运行健康.良好.可是过了一段时间,线上总有人反应查询订单失败,等过了一段时间才能查到.这 ...
随机推荐
- 史上最全的select加锁分析(Mysql)
引言 大家在面试中有没遇到面试官问你下面六句Sql的区别呢 select * from table where id = ? select * from table where id < ? s ...
- java位移运算符2 转
https://blog.csdn.net/xxx134617/article/details/7454774 java中int类型占4个字节,二进制用补码表示: 3的二进制表示: 00000000 ...
- 五、OpenStack—nova组件介绍与安装
一.nova介绍 Nova 是 OpenStack 最核心的服务,负责维护和管理云环境的计算资源.OpenStack 作为 IaaS 的云操作系统,虚拟机生命周期管理也就是通过 Nova 来实现的. ...
- [数据结构] 树状数组 的C程序实现
];//树状数组,用于取区间[x,y]的数据的和 /* & 特殊运算,t&(-t)的值(十进制),就是t在2进制下,从右往左数第一个1出现的位置. 结合树状数组的特殊性质,这个值有用 ...
- H5如何解监听页面退出需求???
事发背景(时间较久): 在一个阳光明媚的一天,这天lz正在工位上悠闲的敲着代码:说时迟那时快,运营小姐姐箭步过来,让lz做一个挽留弹窗:我当时一听这TM不是流氓么.于是便有了以下的故事... 如何实现 ...
- JavaWeb从开发环境搭建,到第一个servlet程序(图文)
## 开学到今天,已经是第三周了~ 然而这门课的教材还没发~ 滋滋滋 表示很“蓝瘦”~~~ Java Web开发环境搭建 1. 下载安装Tomcat 官网地址:http://tomcat. ...
- Linux服务器限制ssh登录,查看登录日志
网络上的服务器很容易受到攻击,最惨的就是被人登录并拿到root权限.有几个简单的防御措施: 1. 修改ssh服务的默认端口 ssh服务的默认端口是22,一般的恶意用户也往往扫描或尝试连接22端口.所以 ...
- Android找回密码功能 手机找回、邮箱找回
找回密码功能设计:https://blog.csdn.net/qq_33472765/article/details/82287404?utm_source=blogxgwz0 手机找回:https: ...
- Python课程学习总结
Python的介绍 Python是一种高级动态.完全面向对象的语言,函数.模块.数字.字符串都是对象,并且完全支持继承.重载.派生.多继承,有益于增强源代码的复用性. Python是一种计算机程序设计 ...
- Dora.Interception,为.NET Core度身打造的AOP框架 [2]:以约定的方式定义拦截器
上一篇<更加简练的编程体验>提供了最新版本的Dora.Interception代码的AOP编程体验,接下来我们会这AOP框架的编程模式进行详细介绍,本篇文章着重关注的是拦截器的定义.采用“ ...