容错处理
容错处理是指软件运行时,能对由非正常因素引起的运行错误给出适当的处理或信息提示,使软件运行正常结束
从解释中可以看出,简单理解,所谓的其实就是捕获异常了,不让异常影响系统的正常运行,正如中的一样。
而在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进行处理,非常感谢!