springCloud熔断器Hystrix
一、为什么要使用熔断器?
在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因“服务提供者”的不可用导致“服务消费者”的不可用,并将不可用逐渐放大的过程。Hystrix组件来进行容错处理。Hystrix是Netflix的一款开源组件,它通过熔断模式、隔离模式、回退(fallback)和限流等机制对服务进行弹性容错保护,保证系统的稳定性。
如果下图所示:A作为服务提供者,B为A的服务消费者,C和D是B的服务消费者。A不可用引起了B的不可用,并将不可用像滚雪球一样放大到C和D时,雪崩效应就形成了。
二、什么是Hystrix
1. 介绍
Hystrix [hɪst'rɪks]的中文含义是豪猪, 因其背上长满了刺,而拥有自我保护能力
2. 原理
Hystrix 能使你的系统在出现依赖服务失效的时候,通过隔离系统所依赖的服务,防止服务级联失败,同时提供失败回退机制,更优雅地应对失效,并使你的系统能更快地从异常中恢复。
3. 功能
1、熔断模式:熔断模式原理类似于电路熔断器,当电路发生短路时,熔断器熔断,保护电路避免遭受灾难性损失。
当服务异常或者大量延时,满足熔断条件时服务调用方会主动启动熔断,执行fallback逻辑直接返回,不会继续调用服务进一步拖垮系统。熔断器默认配置服务调用错误率阀值为50%,超过阀值将自动启动熔断模式。服务隔离一段时间以后,熔断器会进入半熔断状态,即允许少量请求进行尝试,如果仍然调用失败,则回到熔断状态,如果调用成功,则关闭熔断模式。
2、隔离模式:Hystrix默认采用线程隔离,不同的服务使用不同的线程池,彼此之间不受影响,当一个服务出现故障耗尽它的线程池资源,其他的服务正常运行不受影响,达到隔离的效果。例如我们通过andThreadPoolKey配置某个服务使用命名为TestThreadPool的线程池,实现与其他命名的线程池隔离。
3、回退(fallback):fallback机制其实是一种服务故障时的容错方式,原理类似Java中的异常处理。只需要继承HystixCommand并重写getFallBack()方法,在此方法中编写处理逻辑,比如可以直接抛异常(快速失败),可以返回空值或缺省值,也可以返回备份数据等。当服务调用出现异常时,会转向执行getFallBack()。有以下几种情况会触发fallback:
程序抛出非HystrixBadRequestExcepption异常,当抛出HystrixBadRequestExcepption异常时,调用程序可以捕获异常,没有触发fallback,当抛出其他异常时,会触发fallback;
程序运行超时;
熔断启动;
线程池已满。
4、限流: 限流是指对服务的并发访问量进行限制,设置单位时间内的并发数,超出限制的请求拒绝并fallback,防止后台服务被冲垮。
Hystix使用命令模式HystrixCommand包装依赖调用逻辑,这样相关的调用就自动处于Hystrix的弹性容错保护之下。调用程序需要继承HystrixCommand并将调用逻辑写在run()中,使用execute()(同步阻塞)或queue()(异步非阻塞)来触发执行run()。
三、Hystrix的使用:
Hystrix虽然已经停止更新迭代,进入了维护阶段,替代品Resilience4j成为了首先,但是遗留系统还有必要维护更新的。
Hystrix在项目中经常使用的方式主要有三种方式在;
1、继承HystrixCommand实现代理类,把之前的业务逻辑写在run()方法内
代码示例详见:https://github.com/Netflix/Hystrix/wiki/How-To-Use
而且支持同步执行、异步执行(返回Future)及响应式编程方式执行(返回Observable)。
这种适用于大量的方法需要熔断处理,官方给了封装的类库:https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica,aop方式比较简单,省去了大量的重复性的代码量。
spring cloud环境下会帮我们自动配置:
3、feign 结合Hystrix
如果使用spring cloud微服务栈的话,feign是一般要使用的,所以feign自带了组件:https://github.com/OpenFeign/feign/tree/master/hystrix
当然为了性能feign也支持异步返回。返回的对象支持:HystrixCommand<T>、Observable<T>、Single<T>、
CompletableFuture<T>、T。
具体可以看源码:feign.hystrix.HystrixInvocationHandler 的实现:
参考:https://www.jianshu.com/p/271e287e5f01,https://blog.csdn.net/doctor_who2004/article/details/105475843