hystrix学习笔记(二):工作原理简介

来源:互联网 发布:淘宝红包链接怎么复制 编辑:程序博客网 时间:2024/05/24 06:17

hystrix目录

  • hystrix熔断 学习笔记(一)
  • hystrix学习笔记(二):工作原理简介
  • hystrix学习笔记(三):hystrix应用实例
  • hystrix学习笔记(四):hystrix应用配置实例
  • RxJava 驯服数据流之时间平移

hystrix是什么

Hystrix是Netflix开源的一款容错系统,能帮助使用者写出具备强大的容错能力和鲁棒性的程序。

在分布式环境中,不可避免地有许多服务依赖将失败,尤其现在流行的微服务。 Hystrix是一个库,可以通过线程隔离、熔断、服务降级等措施来帮助您控制这些分布式服务之间的交互。

Hystrix可以做到以下事情:

  • 通过控制延迟和故障来保障第三方服务调用的可靠性
  • 在复杂的分布式系统中防止级联故障,防止雪崩
  • 快速失败、快速恢复
  • 优雅降级
  • 提供近时时监控、报警和操作控制

为什么用Hystrix?什么情况下用?

分布式系统中,或者说微服务,各个系统错综复杂,一个系统依赖的服务比较多,而且会有多级依赖。当其中某一个服务出现问题,在高并发的情况下都有可能导致整个系统的瘫痪,蝴蝶效应在这里表现明显。
这里写图片描述
也许你会问为什么会酱紫?如上图,假如服务I出现较严重延迟,这时上层应用访问量tps比较大时, 首先上层应用资源会被占满,并且一般网络请求(http/rpc)都有重试机制,服务I的压力会更大,严重时则会导致应用宕机。
这里写图片描述

hystrix 工作流程

首先看一下官网的流程图:

这里写图片描述

这张图已经完美的诠释了hystrix的工作流程。

下面详细解释一下

HystrixCommand 和 HystrixObservableCommand

上图中的 1

要想使用hystrix,只需要继承HystrixCommand或HystrixObservableCommand。
两者主要区别是:

  • 前者的命令逻辑写在run();后者的命令逻辑写在construct()
  • 前者的run()是由新创建的线程执行;后者的construct()是由调用程序线程执行
  • 前者一个实例只能向调用程序发送(emit)单条数据;后者一个实例可以顺序发送多条数据(onNext)

Command的执行

上图中的 2

execute()、queue()、observe()、toObservable()这4个方法用来触发执行run()/construct(),一个实例只能执行一次这4个方法,特别说明的是HystrixObservableCommand没有execute()和queue()。

4个方法的主要区别是:

  • execute():以同步堵塞方式执行run()。
  • queue():以异步非堵塞方式执行run(),类似于java里的future
  • observe():事件注册前执行run()/construct()。事件注册前,先调用observe()自动触发执行run()/construct()(如果继承的是HystrixCommand,hystrix将创建新线程非堵塞执行run();如果继承的是HystrixObservableCommand,将以调用程序线程堵塞执行construct()),第二步是从observe()返回后调用程序调用subscribe()完成事件注册,如果run()/construct()执行成功则触发onNext()和onCompleted(),如果执行异常则触发onError()
  • toObservable():事件注册后执行run()/construct()。第一步是事件注册前,一调用toObservable()就直接返回一个Observable对象,第二步调用subscribe()完成事件注册后自动触发执行run()/construct()(如果继承的是HystrixCommand,hystrix将创建新线程非堵塞执行run(),调用程序不必等待run();如果继承的是HystrixObservableCommand,将以调用程序线程堵塞执行construct(),调用程序等待construct()执行完才能继续往下走),如果run()/construct()执行成功则触发onNext()和onCompleted(),如果执行异常则触发onError()

另外需要说明的是,这四个方法,最终都是调用toObservable,从上图中也可以看出。

判断缓存

上图中的 3

如果有缓存,则直接从缓存中取,如果没有,则继续发送请求

是否熔断

上图中的4

这里包含两层含义:配置了强制熔断;由于error或timeout超过阈值导致熔断

线程池、信号量、队列满了

上图中的5

容器满了自然需要执行fallback了

真正执行HystrixObservableCommand.construct() or HystrixCommand.run()

上图中的6

需要注意:没有办法强制停止线程工作,最好解决办法是抛出InterruptedException异常。如果被Command包装的功能代码没有抛出InterruptedException异常,即使出现了timeOut,该线程也会继续工作(和http请求超时类似),这样虽然可以熔断,但是其线程资源还是占用的,并没有真正释放资源。大多数httpclient并没有处理InterruptedException异常,所以要正确配置http客户端的链接和超时时间。

计算系统健康值

上图中的7

根据配置的规则计算是否需要熔断

服务隔离

这里写图片描述

服务隔离有两个重要的好处:
- 我们作为服务消费者,去访问不同的外部服务,如果其中一个服务不稳定,有可能导致线程池或者http请求等资源被过多的占用,导致整个系统垮掉(雪崩)。而我们通过对不同的服务的请求进行隔离,就可以做到互补影响,如上图中依赖A如果异常,不会影响到依赖I。
- 我们作为服务的提供方,我们可以动态调整外部服务的访问情况。假如有A/B两个外部调用,在某个大促期间,B是P0级别的服务,必须保证可用,但是A允许降级。那么我们作为服务提供方,就可以将外部调用隔离开来,A的请求降级,保证B的请求。

hystrix可以做到哪些事情

  • 服务隔离
  • 降级
  • 熔断
  • 限流
  • 请求合并
  • 请求缓存

滑动窗口

Hystrix的Metrics中保存了当前服务的健康状况, 包括服务调用总次数和服务调用失败次数等. 根据Metrics的计数, 熔断器从而能计算出当前服务的调用失败率, 用来和设定的阈值比较从而决定熔断器的状态切换逻辑. 因此Metrics的实现非常重要.

Hystrix在这些版本中开始使用RxJava的Observable.window()实现滑动窗口。关于滑动窗口的详细资料,请参考

hystrix中Metrics的配置:

  • metrics.rollingStats.timeInMilliseconds

此属性设置滚动统计窗口分为的桶数。默认10秒。假如设置为10秒,每秒1个桶:
这里写图片描述

  • metrics.rollingStats.numBuckets

此属性设置滚动统计窗口分为的桶数。注意metrics.rollingStats.timeInMilliseconds % metrics.rollingStats.numBuckets == 0必须成立。默认10个。

自定义值
HystrixCommandProperties.Setter().withMetricsRollingStatisticalWindowBuckets(int value)

  • metrics.rollingPercentile.enabled

更多配置请参考 HystrixConfiguration

原创粉丝点击