ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Hystrix工作流程原理

2021-02-23 20:32:22  阅读:228  来源: 互联网

标签:返回 Observable 降级 调用 Hystrix 流程 command 原理


一、Hystrix的介绍

Hystrix是netflix开源的一个容灾框架,解决当外部依赖故障时拖垮业务系统、甚至引起雪崩的问题。

Hystrix是豪猪的意思。豪猪是一种全身是刺的动物,netflix使用Hystrix意味着Hystrix能够像豪猪的刺一样保护你的应用。Hystrix是Netflix(网飞公司)开源的一款容错系统。该框架为分布式环境提供了弹性、增加了延迟容忍和容错。

Hystrix提供了如下操作:

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

二、Hystrix的原理

下面介绍下Hystrix提供的降级、熔断的实现原理。

2.1 工作主流程

Hystrix工作流程图(网上找的):
在这里插入图片描述
下面解释下Hystrix的工作流程:

1、构建一个HystrixCommand或者HystrixObservableCommand对象,生成Hystrix命令

一个 HystrixCommand 或 HystrixObservableCommand 对象,代表了对某个依赖服务发起的一次请求或者调用。创建的时候,可以在构造函数中传入任何需要的参数。

  • HystrixCommand 主要用于仅仅会返回一个结果的调用。
  • HystrixObservableCommand 主要用于可能会返回多条结果的调用。
// 创建 HystrixCommand
HystrixCommand hystrixCommand = new HystrixCommand(arg1, arg2);
// 创建 HystrixObservableCommand
HystrixObservableCommand hystrixObservableCommand = new HystrixObservableCommand(arg1, arg2);

2、执行Hystrix命令
执行 command,就可以发起一次对依赖服务的调用。目前有execute()、queue()、observe()、toObservable()四个方法,其中execute() 和 queue() 方法仅仅对 HystrixCommand 适用。

  • execute() — 同步,直到依赖服务返回单条结果,或者抛出异常,execute()=queue().get();
  • queue() — 异步,返回Future,后面可以通过 Future 获取单条结果,queue()=toObservable().toBlocking().toFuture();
  • observe() — 异步,订阅一个 Observable 对象,Observable 代表的是依赖服务返回的结果,获取到一个那个代表结果的 Observable 对象的拷贝对象。
  • toObservable() — 同步, 返回一个延迟的Observable 对象,如果我们订阅这个对象,就会延迟的开始执行 command 并且获取返回结果。

其中, queue()是异步的,直到Future调用get()方法才成为同步;observe()是订阅后就可以获取Observable 对象,而toObservable() 是订阅后才开始执行command然后获取Observable 对象。

K    value   = hystrixCommand.execute();
Future<K>     fValue  = hystrixCommand.queue();
Observable<K> oValue = hystrixObservableCommand.observe();
Observable<K> toOValue = hystrixObservableCommand.toObservable();
execute() 实际上会调用 queue().get() 方法。
public R execute() {
    try {
        return queue().get();
    } catch (Exception e) {
        throw Exceptions.sneakyThrow(decomposeException(e));
    }
}

而在 queue() 方法中,会调用 toObservable().toBlocking().toFuture()。
final Future delegate = toObservable().toBlocking().toFuture();
也就是说,先通过 toObservable() 获得 Future 对象,然后调用 Future 的 get() 方法。那么,其实无论是哪种方式执行 command,最终都是依赖于 toObservable() 去执行的。
3、检查是否开启缓存
如果这个 command 开启了请求缓存 Request Cache,而且这个调用的结果在缓存中存在,那么直接从缓存中返回结果。否则,继续往后的步骤。
4、检查是否开启了断路器
检查这个 command 对应的依赖服务是否开启了断路器。如果断路器被打开了,那么 Hystrix 就不会执行这个 command,而是直接去执行 fallback 降级机制,返回降级结果。
5、检查线程池/信号量是否已满
如果这个 command 线程池或者 semaphore 信号量已满,那么也不会执行 command,而是直接去调用 fallback 降级机制,同时发送 reject 信息给断路器统计。
6、执行 command
Hystrix会根据我们编写的方法来决定采取什么样的方式去请求依赖服务,通过调用 HystrixObservableCommand 对象的 construct() 方法,或者 HystrixCommand 的 run() 方法来实际执行这个 command。

  • HystrixCommand.run() 返回单条结果,或者抛出异常。
  • HystrixObservableCommand.construct() 返回一个 Observable 对象,可以获取多条结果。

如果是采用线程池方式,并且 HystrixCommand.run() 或者 HystrixObservableCommand.construct() 的执行时间超过了 timeout 时长的话,那么 command 所在的线程会抛出一个 TimeoutException,这时会执行 fallback 降级机制,不会去管 run() 或 construct() 返回的值了。另一种情况,如果 command 执行出错抛出了其它异常,那么也会走 fallback 降级。这两种情况下,Hystrix 都会发送异常事件给断路器统计。
注意,我们是不可能终止掉一个调用严重延迟的依赖服务的线程的,只能说给你抛出来一个 TimeoutException。
如果没有 timeout,也正常执行的话,那么调用线程就会拿到一些调用依赖服务获取到的结果,然后 Hystrix 也会做一些 logging 记录和 metric 度量统计。

7、断路健康检查
Hystrix 会把每一个依赖服务的调用成功、失败、Reject、Timeout 等事件发送给 circuit breaker 断路器。断路器就会对这些事件的次数进行统计,根据异常事件发生的比例来决定是否要进行断路(熔断)。如果打开了断路器,那么在接下来一段时间内,会直接断路,返回降级结果。
如果休眠时间过后,断路器尝试执行 command,调用没有出错,返回了正常结果,那么 Hystrix 就会把断路器关闭。
8、调用 fallback 降级机制
在以下几种情况中,Hystrix 会调用 fallback 降级机制:

  • 断路器处于打开状态;
  • 线程池/队列/semaphore满了;
  • command 执行超时;
  • run() 或者 construct() 抛出异常。
    如果没有实现 fallback,或者 fallback 抛出了异常,Hystrix 会返回一个 Observable,但是不会返回任何数据。

不同的 command 执行方式,其 fallback 为空或者异常时的返回结果不同:

  • 对于 execute(),直接抛出异常。
  • 对于 queue(),返回一个 Future,调用 get() 时抛出异常。
  • 对于 observe(),返回一个 Observable 对象,但是调用 subscribe() 方法订阅它时,立即抛出调用者的 one rror() 方法。
  • 对于 toObservable(),返回一个 Observable 对象,但是调用 subscribe() 方法订阅它时,立即抛出调用者的 one rror() 方法。

不同的 command 执行方式,其正常时的返回结果:

  • execute(),获取一个 Future.get(),然后拿到单个结果。
  • queue(),返回一个 Future对象。
  • observe(),立即订阅 Observable对象,然后启动 8 大执行步骤,返回一个拷贝的 Observable对象,订阅时立即回调给你结果。
  • toObservable(),返回一个延迟的 Observable对象,必须手动订阅才会去执行 8 大步骤。

Hystrix工作流程图(自己画的):
在这里插入图片描述
参考:Hystrix的Command属性解读
读书笔记——spring cloud 中 HystrixCommand的四种执行方式简述

标签:返回,Observable,降级,调用,Hystrix,流程,command,原理
来源: https://blog.csdn.net/mameng1988/article/details/114001903

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有