SpringCloud容错处理:Hystrix源码分析

容错处理

容错处理是指软件运行时,能对由非正常因素引起的运行错误给出适当的处理或信息提示,使软件运行正常结束

从解释中可以看出,简单理解,所谓的其实就是捕获异常了,不让异常影响系统的正常运行,正如中的一样。

而在SpringCloud微服务调用中,自身异常可自行处理外,对于依赖的服务若发生错误,或者调用异常,或者调用时间过长等原因时,避免长时间等待,造成系统资源耗尽。
一般上都会通过,如请求中的和;再或者就是使用模式,隔离问题服务,防止级联错误等。

为了防止服务之间的调用异常造成的连锁反应,在SpringCloud中提供了Hystrix组件来实现服务调用异常的处理,或对高并发情况下的服务降级处理 。

什么是Hystrix

 在分布式系统中,服务与服务之间依赖错综复杂,一种不可避免的情况就是某些服务将会出现失败。

Hystrix是一个库,它提供了服务与服务之间的容错功能,主要体现在延迟容错和容错,从而做到控制分布式系统中的联动故障。Hystrix通过隔离服务的访问点,阻止联动故障,并提供故障的解决方案,从而提高了这个分布式系统的弹性。

Hystrix容错机制:

  • 包裹请求使用HystrixCommand包裹对依赖的调用逻辑,每个命令在独立线程中执行,这是用到了设计模式“命令模式”。
  • 跳闸机制:当某服务的错误率超过一定阈值时,Hystrix可以自动或手动跳闸,停止请求该服务一段时间
  • 资源隔离Hystrix为每个依赖都维护了一个小型的线程池,如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等候,从而加速判定失败。
  • 监控:Hystrix可以近乎实时的监控运行指标和配置的变化。如成功、失败、超时、被拒绝的请求等。
  • 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑。回退逻辑可自定义。
  • 自我修复:断路器打开一段时间后,会自动进入半开状态,断路器打开、关闭、半开的逻辑转换

下图就是的回退策略,防止级联故障。

Hystrix的简单使用

1.要使用 Hystrix熔断机制处理引入它本身的依赖之外,我们需要在主程序配置类上引入 @EnableHystrix 标签 开启Hystrix功能,如下

2.开启Hystrix熔断机制后,对方法进行熔断处理

当hiService方法第调用异常,会触发 fallbackMethod执行的hiError方法做成一些补救处理

Hystrix的工作原理

下图显示通过Hystrix向服务依赖关系发出请求时会发生什么:

具体将从以下几个方面进行描述:

1.构建一个HystrixCommand或者HystrixObservableCommand 对象。

第一步是构建一个HystrixCommand或HystrixObservableCommand对象来表示你对依赖关系的请求。 其中构造函数需要和请求时的参数一致。

构造HystrixCommand对象,如果依赖关系预期返回单个响应。 可以这样写:

同理,可以构建HystrixObservableCommand :

2.执行Command

通过使用Hystrix命令对象的以下四种方法之一,可以执行该命令有四种方法(前两种方法仅适用于简单的HystrixCommand对象,并不适用于HystrixObservableCommand):

  • execute()–阻塞,,然后返回从依赖关系接收到的单个响应(或者在发生错误时抛出异常)
  • queue()–返回一个可以从依赖关系获得单个响应的future 对象
  • toObservable() –返回一个Observable,当您订阅它时,将执行Hystrix命令并发出其响应

同步调用execute()调用queue().get(). queue()依次调用toObservable().toBlocking().toFuture()。 这就是说,最终每个HystrixCommand都由一个Observable实现支持,甚至是那些旨在返回单个简单值的命令。

3.响应是否有缓存/h2>

如果为该命令启用请求缓存,并且如果缓存中对该请求的响应可用,则此缓存响应将立即以“可观察”的形式返回。

4.断路器是否打开/h2>

当您执行该命令时,Hystrix将检查断路器以查看电路是否打开。

如果电路打开(或“跳闸”),则Hystrix将不会执行该命令,但会将流程路由到(8)获取回退。

如果电路关闭,则流程进行到(5)以检查是否有可用于运行命令的容量。

5.线程池/队列/信 量是否已经满负载/h2>

如果与命令相关联的线程池和队列(或信 量,如果不在线程中运行)已满,则Hystrix将不会执行该命令,但将立即将流程路由到(8)获取回退。

6.HystrixObservableCommand.construct() 或者 HystrixCommand.run()

在这里,Hystrix通过您为此目的编写的方法调用对依赖关系的请求,其中之一是:

  • HystrixCommand.run() – 返回单个响应或者引发异常
  • HystrixObservableCommand.construct() – 返回一个发出响应的Observable或者发送一个onError通知

如果run()或construct()方法超出了命令的超时值,则该线程将抛出一个TimeoutException(或者如果命令本身没有在自己的线程中运行,则会产生单独的计时器线程)。 在这种情况下,Hystrix将响应通过8进行路由。获取Fallback,如果该方法不取消/中断,它会丢弃最终返回值run()或construct()方法。

请注意,没有办法强制潜在线程停止工作 – 最好的Hystrix可以在JVM上执行它来抛出一个InterruptedException。 如果由Hystrix包装的工作不处理InterruptedExceptions,Hystrix线程池中的线程将继续工作,尽管客户端已经收到了TimeoutException。 这种行为可能使Hystrix线程池饱和,尽管负载“正确地流失”。 大多数Java HTTP客户端库不会解释InterruptedExceptions。 因此,请确保在HTTP客户端上正确配置连接和读/写超时。

如果该命令没有引发任何异常并返回响应,则Hystrix在执行某些日志记录和度量 告后返回此响应。 在run()的情况下,Hystrix返回一个Observable,发出单个响应,然后进行一个onCompleted通知; 在construct()的情况下,Hystrix返回由construct()返回的相同的Observable。

7.计算Circuit 的健康

Hystrix向断路器 告成功,失败,拒绝和超时,该断路器维护了一系列的计算统计数据组。

它使用这些统计信息来确定电路何时“跳闸”,此时短路任何后续请求直到恢复时间过去,在首次检查某些健康检查之后,它再次关闭电路。

8.获取Fallback

当命令执行失败时,Hystrix试图恢复到你的回退:当construct()或run()(6.)抛出异常时,当命令由于电路断开而短路时(4.),当 命令的线程池和队列或信 量处于容量(5.),或者当命令超过其超时长度时。

编写Fallback ,它不一依赖于任何的 络依赖,从内存中获取获取通过其他的静态逻辑。如果你非要通过 络去获取Fallback,你可能需要些在获取服务的接口的逻辑上写一个HystrixCommand。

9.返回成功的响应

如果Hystrix命令成功,它将以Observable的形式返回对呼叫者的响应或响应。 根据您在上述步骤2中调用命令的方式,此Observable可能会在返回给您之前进行转换:

  • execute() – 以与.queue()相同的方式获取Future,然后在此Future上调用get()来获取Observable发出的单个值
  • queue() – 将Observable转换为BlockingObservable,以便将其转换为Future,然后返回此未来
  • observe() – 立即订阅Observable并启动执行命令的流程; 返回一个Observable,当您订阅它时,重播排放和通知
  • toObservable() – 返回Observable不变; 您必须订阅它才能实际开始导致命令执行的流程

Hystrix的源码解析

1. @EnableHystrix 开启Hystrix

沿着我上面的使用方式来跟踪一下 Hystrix的 源码。

首先我们看一下标签:@EnableHystrix ,他的作用从名字就能看出就是开启Hystrix ,我们看一下它的源码

它上面有一个注解:@ EnableCircuitBreaker (熔断器),那么@ EnableHystrix标签的本质其实是@ EnableCircuitBreaker ,我们看一下他的源码

@EnableCircuitBreaker标签引入了一个@Import(EnableCircuitBreakerImportSelector.class) 类,字面翻译的意思是开启熔断器的导入选择器 ,导入什么东西呢源码

其实EnableCircuitBreakerImportSelector的作用就是去导入熔断器的配置 。其实Spring中也有类似于JAVA SPI 的加载机制, 即会自动加载 jar包 spring-cloud-netflix-core 中的META-INF/spring.factories 中的Hystrix相关的自动配置类
注:SPI : 通过将服务的接口与实现分离以实现解耦,提高程序拓展性的机制,达到插拔式的效果 。

 

HystrixCircuitBreakerConfiguration 就是针对于 Hystrix熔断器的配置

在该配置类中创建了 HystrixCommandAspect

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年1月26日
下一篇 2020年1月26日

相关推荐