战狂粗人张

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

一.Hystrix是什么

Hystrix是Netflix开源的一款容错框架,具有自我保护能力。为了实现容错和自我保护。

包含常用的容错方法:线程池隔离、信号量隔离、熔断、降级回退。在高并发访问下,系统所依赖的服务的稳定性对系统的影响非常大,依赖有很多不可控的因素,

比如网络连接变慢,资源突然繁忙,暂时不可用,服务脱机等。我们要构建稳定、可靠的分布式系统,就必须要有这样一套容错方法。

在分布式环境中,许多服务依赖项中的一些必然会失败。Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互。

Hystrix通过隔离服务之间的访问点、停止级联失败和提供回退选项来实现这一点,所有这些都可以提高系统的整体弹性。

 

二.Hystrix能做什么

Hystrix也是Netflix套件的一部分。他的功能是,当对某个服务的调用在一定的时间内(默认10s,由metrics.rollingStats.timeInMilliseconds配置),

有超过一定次数(默认20次,由circuitBreaker.requestVolumeThreshold参数配置)并且失败率超过一定值(默认50%,由circuitBreaker.errorThresholdPercentage配置),该服务的断路器会打开。

返回一个由开发者设定的fallback

 

fallback可以是另一个由Hystrix保护的服务调用,也可以是固定的值。fallback也可以设计成链式调用,先执行某些逻辑,再返回fallback。

(1)对通过第三方客户端库访问的依赖项(通常是通过网络)的延迟和故障进行保护和控制。

(2)在复杂的分布式系统中阻止级联故障。

(3)快速失败,快速恢复。

(4)回退,尽可能优雅地降级。

(5)启用近实时监控、警报和操作控制。

 

作用:

通过hystrix可以解决雪崩效应问题,它提供了资源隔离、降级机制、融断、缓存等功能。

资源隔离:包括线程池隔离和信号量隔离,限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。

降级机制:超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据。

融断:当失败率达到阀值自动触发降级(如因网络故障/超时造成的失败率高),熔断器触发的快速失败会进行快速恢复。

缓存:返回结果缓存,后续请求可以直接走缓存。

请求合并:可以实现将一段时间内的请求(一般是对同一个接口的请求)合并,然后只对服务提供者发送一次请求。

 

三.Hystrix原理

1、Hystrix处理流程

Hystrix整个工作流如下:

 

 

(1)构造一个 HystrixCommand或HystrixObservableCommand对象,用于封装请求,并在构造方法配置请求被执行需要的参数;

(2)执行命令,Hystrix提供了4种执行命令的方法,后面详述;

(3)判断是否使用缓存响应请求,若启用了缓存,且缓存可用,直接使用缓存响应请求。Hystrix支持请求缓存,但需要用户自定义启动;

(4)判断熔断器是否打开,如果打开,跳到第8步;

(5)判断线程池/队列/信号量是否已满,已满则跳到第8步;

(6)执行HystrixObservableCommand.construct()或HystrixCommand.run(),如果执行失败或者超时,跳到第8步;否则,跳到第9步;

(7)统计熔断器监控指标;

(8)走Fallback备用逻辑;

(9)返回请求响应;

从流程图上可知道,第5步线程池/队列/信号量已满时,还会执行第7步逻辑,更新熔断器统计信息,而第6步无论成功与否,都会更新熔断器统计信息。

 

2、Hystrix容错

Hystrix的容错主要是通过添加容许延迟和容错方法,帮助控制这些分布式服务之间的交互。 还通过隔离服务之间的访问点,阻止它们之间的级联故障以及提供回退选项来实现这一点,从而提高系统的整体弹性。

Hystrix主要提供了以下几种容错方法:

(1)资源隔离

资源隔离主要指对线程的隔离。Hystrix提供了两种线程隔离方式:线程池和信号量。

a、线程隔离-线程池

Hystrix通过命令模式对发送请求的对象和执行请求的对象进行解耦,将不同类型的业务请求封装为对应的命令请求。并且为每个类型的Command配置一个线程池,当第一次创建Command时,根据配置创建一个线程池,并放入ConcurrentHashMap。

b、线程隔离-信号量

上面提到了线程池隔离的缺点,当依赖延迟极低的服务时,线程池隔离技术引入的开销超过了它所带来的好处。这时候可以使用信号量隔离技术来代替,通过设置信号量来限制对任何给定依赖的并发调用量。

使用线程池时,发送请求的线程和执行依赖服务的线程不是同一个,而使用信号量时,发送请求的线程和执行依赖服务的线程是同一个,都是发起请求的线程。

总结:

线程池和信号量都支持熔断和限流。相比线程池,信号量不需要线程切换,因此避免了不必要的开销。但是信号量不支持异步,也不支持超时,也就是说当所请求的服务不可用时,信号量会控制超过限制的请求立即返回,

但是已经持有信号量的线程只能等待服务响应或从超时中返回,即可能出现长时间等待。线程池模式下,当超过指定时间未响应的服务,Hystrix会通过响应中断的方式通知线程立即结束并返回。

 

(2)熔断

Hystrix在运行过程中会向每个commandKey对应的熔断器报告成功、失败、超时和拒绝的状态,熔断器维护并统计这些数据,并根据这些统计信息来决策熔断开关是否打开。

如果打开,熔断后续请求,快速返回。隔一段时间(默认是5s)之后熔断器尝试半开,放入一部分流量请求进来,相当于对依赖服务进行一次健康检查,如果请求成功,熔断器关闭。

每个熔断器默认维护10个bucket,每秒一个bucket,每个blucket记录成功,失败,超时,拒绝的状态,默认错误超过50%且10秒内超过20个请求进行中断拦截。

 

(3)降级

降级,通常指务高峰期,为了保证核心服务正常运行,需要停掉一些不太重要的业务,或者某些服务不可用时,执行备用逻辑从故障服务中快速失败或快速返回,以保障主体业务不受影响。

Hystrix提供的降级主要是为了容错,保证当前服务不受依赖服务故障的影响,从而提高服务的健壮性。要支持回退或降级处理,可以重写HystrixCommand的getFallBack方法或HystrixObservableCommand的resumeWithFallback方法。

Hystrix一共有如下几种降级回退模式:

a、Fail Fast 快速失败

b、Fail Silent 无声失败

c、Fallback: Static 返回默认值:回退的时候返回静态嵌入代码中的默认值,这样就不会导致功能以Fail Silent的方式被清楚,也就是用户看不到任何功能了。而是按照一个默认的方式显示。

d、Fallback: Stubbed 自己组装一个值返回:当执行返回的结果是一个包含多个字段的对象时,则会以Stubbed 的方式回退。Stubbed 值我们建议在实例化Command的时候就设置好一个值。

e、Fallback: Cache via Network 利用远程缓存。通过远程缓存的方式。在失败的情况下再发起一次remote请求,不过这次请求的是一个缓存比如redis。

     由于是又发起一起远程调用,所以会重新封装一次Command,这个时候要注意,执行fallback的线程一定要跟主线程区分开,也就是重新命名一个ThreadPoolKey。

 

3、合并请求collapsing

Hystrix支持N个请求自动合并为一个请求,这个功能在有网络交互的场景下尤其有用,比如每个请求都要网络访问远程资源,如果把请求合并为一个,将使多次网络交互变成一次,极大节省开销。

重要一点,两个请求能自动合并的前提是两者足够“近”,即两者启动执行的间隔时长要足够小,默认为10ms,即超过10ms将不自动合并。

 

posted on 2020-06-01 00:54  战狂粗人张  阅读(123)  评论(0编辑  收藏  举报