参考链接:http://www.jianshu.com/p/e07661b9bae8

一、前言

大型复杂的分布式系统中,高可用相关的技术架构非常重要。
高可用架构非常重要的一个环节,就是如何将分布式系统中的各个服务打造成高可用的服务,从而足以应对分布式系统环境中的各种各样的问题,,避免整个分布式系统被某个服务的故障给拖垮。
比如:

  • 服务间的调用超时
  • 服务间的调用失败

要解决这些棘手的分布式系统可用性问题,就涉及到了高可用分布式系统中的很多重要的技术,包括:

  • 资源隔离
  • 限流与过载保护
  • 熔断
  • 优雅降级
  • 容错
  • 超时控制
  • 监控运维

二、运行原理

Hystrix是国外知名的视频网站Netflix所开源的非常流行的高可用架构框架。Hystrix能够完美的解决分布式系统架构中打造高可用服务面临的一系列技术难题。

Hystrix “豪猪”,具有自我保护的能力。hystrix 通过如下机制来解决雪崩效应问题。

  • 资源隔离:包括线程池隔离和信号量隔离,限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。
  • 降级机制:超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据。
  • 融断:当失败率达到阀值自动触发降级(如因网络故障/超时造成的失败率高),熔断器触发的快速失败会进行快速恢复。
  • 缓存:提供了请求缓存、请求合并实现。

Hystrix支持实时监控、报警、控制(修改配置)。

(1)线程池隔离模式:使用一个线程池来存储当前请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求先入线程池队列。这种方式要为每个依赖服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)
(2)信号量隔离模式:使用一个原子计数器(或信号量)记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃该类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)

 

熔断

正常情况下,断路器处于关闭状态(Closed),
如果调用持续出错或者超时,电路被打开进入熔断状态(Open),后续一段时间内的所有调用都会被拒绝(Fail Fast),
一段时间以后,保护器会尝试进入半熔断状态(Half-Open),允许少量请求进来尝试,
        如果调用仍然失败,则回到熔断状态
        如果调用成功,则回到电路闭合状态;

降级

服务降级的目的保证上游服务的稳定性,当整体资源快不够了,将某些服务先关掉,待渡过难关,再开启回来。

三、调用过程

工作流程(参考:https://github.com/Netflix/Hystrix/wiki/How-it-Works

1、 创建一个 HystrixCommand 或 HystrixObservableCommand 实例

第一步就是构建一个 HystrixCommand 或 HystrixObservableCommand 实例来向其它组件发出操作请求,通过构造方法来创建实例。

HystrixCommand:返回一个单响应

HystrixObservableCommand:返回一个观察者发出的响应

2、 执行方法

这里有4个方法,前两个只适用于 HystrixCommand 不适用于 HystrixObservableCommand

execute():阻塞型方法,返回单个结果(或者抛出异常)

queue():异步方法,返回一个 Future 对象,可以从中取出单个结果(或者抛出异常)

  • observe():返回Observable 对象

toObservable():返回Observable 对象

3、 缓存判断

检查缓存内是否有对应指令的结果,如果有的话,将缓存的结果直接以 Observable 对象的形式返回 

4、 断路器判断

检查Circuit Breaker的状态。如果Circuit Breaker的状态为开启状态,Hystrix将不会执行对应指令,而是直接进入失败处理状态(图中8)。如果Circuit Breaker的状态为关闭状态,Hystrix会继续执行(图5)

5、 线程池、任务队列、信号量的检查

确认是否有足够的资源执行操作指令。当线程池和队列(或者是信号量,当不使用线程池隔离模式的时候)资源满的时候,Hystrix将不会执行对应指令并且会直接进入失败处理状态(图8)

6、 HystrixObservableCommand.construct() 和 HystrixCommand.run()

如果资源充足,Hystrix将会执行操作指令。操作指令的调用最终都会到这两个方法:

HystrixCommand.run():返回一个响应或者抛出一个异常

HystrixObservableCommand.construct():返回一个可观测的发出响应(s)或发送一个onError通知

如果执行指令的时间超时,执行线程会抛出 TimeoutException 异常。Hystrix会抛弃结果并直接进入失败处理状态。如果执行指令成功,Hystrix会进行一系列的数据记录,然后返回执行的结果。

7、 统计断路器的健康情况

Hystrix会根据记录的数据来计算失败比率,一旦失败比率达到某一阈值将自动开启Circuit Breaker 

8、 回退

如果我们在Command中实现了HystrixCommand.getFallback()方法(或HystrixObservableCommand. resumeWithFallback() 方法,Hystrix会返回对应方法的结果。如果没有实现这些方法的话,仍然 Hystrix会返回一个空的 Observable 对象,并且可以通过 onError 来终止并处理错误。

调用不同的方法返回不同的结果:

execute(): 将会抛出异常

queue(): 将会返回一个Future 对象,如果调用它的get()方法将会抛出异常

  • observe()和 toObservable():都会返回上述的 Observable 对象

9、 返回成功

如果Hystrix执行成功,返回的响应取决于在步骤2中调用命令。

execute():阻塞型方法,返回单个结果(或者抛出异常)

queue():异步方法,返回一个 Future 对象,可以从中取出单个结果(或者抛出异常)

  • observe():返回Observable 对象

toObservable():返回Observable 对象

断路器的工作原理

断路器开启或者关闭的条件:

1、  当满足一定的阀值的时候(默认10秒内超过20个请求次数)

2、  当失败率达到一定的时候(默认10秒内超过50%的请求失败)

3、  到达以上阀值,断路器将会开启

4、  当开启的时候,所有请求都不会进行转发

5、  一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4

SpringCloud的Hystrix(五) Hystrix机制的更多相关文章

  1. SpringCloud Netflix (五) : Hystrix 服务熔断和服务降级

    什么是Hystrix 在分布式环境中,许多服务依赖项中的一些服务依赖不可避免地会失败.Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助您控制这些分布式服务之间的交互.Hystrix通过隔离服务 ...

  2. springcloud使用之断路器hystrix

    上一篇文章提到我们最近开了个新项目,目的是将新的业务放到新项目中,老项目单独维护,再逐步迁移老项目到新项目里.但就在前端时间生产环境发生了一个事故,事故开始的异常是我们的业务发现前端h5页面办理很慢, ...

  3. SpringCloud与微服务Ⅷ --- Hystrix断路器

    复杂的分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败. 服务雪崩 多个微服务之间调用的时候,假设微服务调用服务B和微服务C,微服务B和微服务C又调用其他服务,这就是 ...

  4. SpringCloud(三)Hystrix断路器

    Hystrix断路器 概述 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败 服务雪崩 多个微服务之间调用的时候,假设微服务A调用微服务B和 ...

  5. SpringCloud笔记六:Hystrix

    目录 Hystrix是什么? Hystrix服务熔断 新建Hystrix项目 修改yml Maven的pom.xml添加hystrix引用 修改Controller Hystrix服务降级 修改api ...

  6. 使用Hystrix的插件机制,解决在使用线程隔离时,threadlocal的传递问题

    背景 在我们的项目中,比较广泛地使用了ThreadLocal,比如,在filter层,根据token,取到用户信息后,就会放到一个ThreadLocal变量中:在后续的业务处理中,就会直接从当前线程, ...

  7. ④SpringCloud 实战:引入Hystrix组件,分布式系统容错

    这是SpringCloud实战系列中第4篇文章,了解前面第两篇文章更有助于更好理解本文内容: ①SpringCloud 实战:引入Eureka组件,完善服务治理 ②SpringCloud 实战:引入F ...

  8. SpringCloud学习笔记(3)——Hystrix

    参考Spring Cloud官方文档第13.14.15章 13. Circuit Breaker: Hystrix Clients Netflix提供了一个叫Hystrix的类库,它实现了断路器模式. ...

  9. <Spring Cloud>入门五 hystrix

    1.服务熔断 1.1引入坐标 <dependency> <groupId>org.springframework.cloud</groupId> <artif ...

随机推荐

  1. LeetCode之Easy篇 ——(1)Two Sum

    1.Two Sum Given an array of integers, return indices of the two numbers such that they add up to a s ...

  2. Unity 网格合并

    从优化角度,Mesh需要合并. 从换装的角度(这里指的是换形状.换组成部件的换装,而不是挂点型的换装),都需要网格合并.材质合并.如果是人物的换装,那么需要合并SkinnedMeshRenderer, ...

  3. linux kexec内核引导

    linux kexec 介绍 kexec的功能是用一个运行的内核去运行一个新内核,就像运行一个应用程序一样.这种机制因为跳过了bootloader,可以实现系统的快速重启.另外kdump也是基于kex ...

  4. Redis搭建多台哨兵

    搭建多台哨兵 完成spring管理多台哨兵 学习redis如何数据持久化如何管理内存 Redis集群搭建 集群测试 Spring管理集群 2 搭建多台哨兵 2.1 搭建步骤 2.1.1 修改6379哨 ...

  5. 8.String StringBuffer StringBuilder

    http://www.cnblogs.com/xiohao/p/4271140.html

  6. poj-1146 ID codes

    Description It is 2084 and the year of Big Brother has finally arrived, albeit a century late. In or ...

  7. zabbix监控redis性能

    创建采集脚本 mkdir -p /etc/zabbix/scripts chown -R zabbix.root /etc/zabbix/scripts vim redis_status.sh  #! ...

  8. 【源码分析】你必须知道的string.IsNullOrEmpty && string.IsNullOrWhiteSpace

    写在前面 之前自信撸码时踩了一次小坑,代码如下: private static void AppServer_NewMessageReceived(WebSocketSession session, ...

  9. (Matlab)GPU计算及CPU计算能力的比较

    %%首先以200*200的矩阵做加减乘除 做比较 t = zeros(1,100); A = rand(200,200);B = rand(200,200);C = rand(200,200); fo ...

  10. [luogu1168]中位数_优先队列

    中位数 题目大意:输出读入的前2*k+1个数的中位数.一共有n个数,按照读入顺序. 注释:$1\le n \le 10^9$. 想法:这是优先队列的一个应用qwq.我们弄两个堆.小根堆和大根堆,保证: ...