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调用的.刚开始没有任何问题,项目运行健康.良好.可是过了一段时间,线上总有人反应查询订单失败,等过了一段时间才能查到.这 ...
随机推荐
- flink学习
flink介绍: Apache Flink is an open source platform for distributed stream and batch data processing. F ...
- 使用python将数据写入excel
先来个简单的例子: #!/usr/bin/python #coding=utf-8 # ======================================================== ...
- hbase_1
常见的RDBMS:(数据库排行) ** mysql --开源[社区版] .收费[企业版] --市场占有率高.web领域被广泛使用 ** 2008年被oracle收购 ** mysql主从架构[集群的一 ...
- Django缓存机制
缓存介绍 在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增删改查,渲染模板,执行业务逻辑,最后生成用户看到的页面. 当一个网站的用户访问量很大的时候,每一次的后台操作,都会消耗很多的服务 ...
- 左倾堆C++实现
#include <iostream> #include <vector> #include <queue> using namespace std; templa ...
- VMware ESXi 6.5 安装
1.1下载esxi镜像 此处我使用的版本是:VMware-VMvisor-Installer-6.5.0-4564106.x86_64 1.2新建一个虚拟机,硬件兼容性处选择ESXI6.5 硬盘40g ...
- mybatis 之数据库 include refid ="base_column_list"
mybatis 之数据库 include refid ="base_column_list" 对于刚学习使用SSM框架的新手来说,mybatis中的数据库语句有点不一样,下面便是对 ...
- linux configure 应用
linux下configure命令详细介绍 2018年01月11日 15:02:20 冷月霜 阅读数:705 标签: configure 更多 个人分类: 数据库技术 Linux环境下的软件安装, ...
- vue的风格指南(必要的)
1.v-if与v-for不要放在同一个元素上 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级.永远不要把 v-if 和 v-for 同时用在同一个元素上. 一般我 ...
- js 原型链的介绍
对象的原型链:一个对象所拥有的属性不仅仅是它本身拥有的属性,他还会从其他对象中继承一些属性.当js在一个对象中找不到需要的属性时,它会到这个对象的父对象上去找,以此类催,这就构成了对象的原型链. 下面 ...