接上一篇:《Hystrix介绍

流程图

下面这幅图相当重要

稍微解释一下上面的流程:

  1. Construct a HystrixCommand or HystrixObservableCommand Object
  2. Execute the Command
  3. Is the Response Cached?
  4. Is the Circuit Open?
  5. Is the Thread Pool/Queue/Semaphore Full?
  6. HystrixObservableCommand.construct() or HystrixCommand.run()
  7. Calculate Circuit Health
  8. Get the Fallback
  9. 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交互的,以及它的逻辑和决策流程,包括断路器中计数器的行为。

上面的流程可以这样描述:

  1. 假设整个电路的体积达到一定的阈值
  2. 假设错误百分比超过设定的错误百分比阈值
  3. 断路器从CLOSED变成OPEN
  4. 当它打开时,经过这个断路器的所有请求被短路
  5. 过了一段时间以后,下一个单个请求被允许通过(此时是半打开状态)。如果这个请求失败,在接下来的睡眠窗口期间断路器保持OPEN状态;如果这个请求成功,断路器转成CLOSED状态;然后继续执行第1步,如此反复。

隔离

Hystrix使用隔板模式来隔离彼此的依赖关系,并限制对其中任何一个的并发访问。

线程和线程池

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

线程池的好处

  1. 应用程序被完全保护而不受失控的客户端的影响。给定的依赖项的线程池可以填满,而不会影响应用程序的其余部分。
  2. 应用程序可以接收新的客户端请求
  3. 当失败的客户端再次恢复正常时,线程池将被清理,应用程序将立即恢复正常的性能
  4. 如果一个客户端配置错误,线程池的健康将会很快地证明这一点(通过增加错误、延迟、超时、拒绝等),并且您可以处理它(通常是通过动态属性进行实时处理),而不会影响应用程序的功能。

Semaphores(信号量)

你可以用信号量(或者计数器)来限制对任意依赖项并发调用的数量,代替用线程池的大小。

HystrixCommand 和 HystrixObservableCommand 在两个地方支持用信号量:

  • Fallback:当Hystrix恢复fallbacks时它总是调用Tomcat的线程这样做
  • Execution:如果设置属性execution.isolation.strategy为SEMAPHORE,那么,Hystrix将使用信号量而不是线程来限制调用该命令的发父线程的并数量。

https://github.com/Netflix/Hystrix/wiki/How-it-Works

Hystrix是如何工作的的更多相关文章

  1. hystrix文档翻译之工作原理

    流程图 下面的图片显示了一个请求在hystrix中的流程图. 1.构造一个HystrixCommand或者HystrixObservableCommand对象 第一步是创建一个HystrixComma ...

  2. 从源码分析Hystrix工作机制

    一.Hystrix解决了什么问题? 在复杂的分布式应用中有着许多的依赖,各个依赖都有难免在某个时刻失败,如果应用不隔离各个依赖,降低外部的风险,那容易拖垮整个应用. 举个电商场景中常见的例子,比如订单 ...

  3. springcloud之hystrix熔断器-Finchley.SR2版

    本篇和大家分享的是springcloud-hystrix熔断器,其主要功能是对某模块调用失败做断路和降级,简单点就当某个模块程序出问题了并达到某阈值就限制后面请求,并降级的方式提供一个默认返回数据.最 ...

  4. Hystrix针对不可用服务的保护机制以及引入缓存

    之前我写过一篇博文,通过案例了解Hystrix的各种基本使用方式,在这篇文章里,我们是通过Hystrix调用正常工作的服务,也就是说,Hytrix的保护机制并没有起作用,这里我们将在HystrixPr ...

  5. SpringCloud中使用Hystrix

    1.  引言 一般而言,一个服务都是部署了多台机器的,那么在这种情况下,当其中一个服务挂了以后Hystrix是怎么处理的呢? 为了验证这个问题,我们准备两个服务:user-api 和 app-gate ...

  6. Spring Boot 集成 Hystrix

    续: <Hystrix介绍> <Hystrix是如何工作的> <SpringCloud学习笔记(3)——Hystrix> Hystrix使用 package com ...

  7. Hystrix 配置参数全解析

    code[class*="language-"], pre[class*="language-"] { background-color: #fdfdfd; - ...

  8. SpringCloud (十) Hystrix Dashboard单体监控、集群监控、与消息代理结合

    一.前言 Dashboard又称为仪表盘,是用来监控项目的执行情况的,本文旨在Dashboard的使用 分别为单体监控.集群监控.与消息代理结合. 代码请戳我的github 二.快速入门 新建一个Sp ...

  9. 使用Hystrix进行微服务降级管理

    前言:目前我们的项目是微服务架构,基于dubbo框架,服务之间的调用是通过rpc调用的.刚开始没有任何问题,项目运行健康.良好.可是过了一段时间,线上总有人反应查询订单失败,等过了一段时间才能查到.这 ...

随机推荐

  1. xpath解析html

    XPath XPath 是一门在 XML 文档中查找信息的语言.XPath 可用来在 XML 文档中对元素和属性进行遍历.XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XP ...

  2. Linux学习之基本操作命令

    目录基本操作命令 列目录内容ls ls  [options]  [files]  #options是可选参数 常用可选参数:-a 所有文件及目录 -A 等同于-a,但是不列出.以及..   -l 长格 ...

  3. Invitation Cards POJ - 1511 (双向单源最短路)

    In the age of television, not many people attend theater performances. Antique Comedians of Malidine ...

  4. Nvidia的CUDA库现在恢复使用了

    Nvidia的CUDA库现在恢复使用了   由于早期版本存在兼容问题,从去年8月nvidia-cuda-toolkit包被移除了.现在该软件包更新后,又重新可以用,被重新添加到Kali Linux软件 ...

  5. PHP调用微博接口实现微博登录的方法示例

    在平时项目开发过程中,除了注册本网站账号进行登录之外,还可以调用第三方接口进行登录网站.这里以微博登录为例.微博登录包括身份认证.用户关系以及内容传播.允许用户使用微博帐号登录访问第三方网站,分享内容 ...

  6. Autograd:自动微分

    Autograd 1.深度学习的算法本质上是通过反向传播求导数,Pytorch的Autograd模块实现了此功能:在Tensor上的所有操作,Autograd都能为他们自动提供微分,避免手动计算导数的 ...

  7. mysql命名规范

    1.数据库表命名规范: (1)表名前应该加上前缀,表的前缀一个用系统或模块的英文名称缩写,前缀全部大写或首字母大写,表名中包含的单词首字母大写. (2)数据库表名应该有意义,并且易于理解,最好使用可以 ...

  8. 201771010126 王燕《面向对象程序设计(Java)》第十三周学习总结

    实验十三  图形界面事件处理技术 实验时间 2018-11-22 1.实验目的与要求 (1) 掌握事件处理的基本原理,理解其用途: 事件源 (eventevent eventeventsource s ...

  9. NOIP2017感悟

    Day1 第一次会做的题这么多却比以前靠的更差. 其实停课期间水平还是提升了很多,但是做题速度和心态问题一就是我最难克服的一个地方. 题目很简单,但是又很恶心,主要是我代码能力太差,第二题调不出来,第 ...

  10. PHP 5.x和PHP 7 Closure不同行为问题

    同样一段闭包代码,PHP 7 ok的,PHP 5.5.11(Windows 开发机器)上却报错,以为是PHP 5 bug,原来是用法不对,记录一下~ 原代码(自己写的框架的路由部分)最初是这样写的: ...