Spring Cloud Hystrix
1 Hystrix概述
Hystrix是一个针对分布式系统容错处理的开源组件,Hystrix单词意为“豪猪”,浑身有刺来保护自己,Hystrix库就是这样一个用来捍卫应用程序健康的利器。它旨在隔离远程系统、服务和第三方库,阻止级联故障,在复杂的分布式系统中实现恢复能力。
现实生活中,可能大家都有注意到家庭电路中通常会安装一个保险盒,当负载过载时,保险盒中的保险丝会自动熔断,以保护电路及家里的各种电器,这就是熔断器的一个常见例子。
2 Hystrix应用场景
- 防止雪崩:在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因“服务提供者”的不可用导致“服务消费者”的不可用,并将不可用逐渐放大的过程。
- 跳闸机制:当某服务失败率达到一定的阈值时,Hystrix可以自动跳闸,停止请求该服务一段时间。
- 资源隔离:Hystrix为每个请求的依赖都维护了一个小型线程池,如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等候,从而加速失败判定。防止级联失败。
- 快速失败:Fail Fast。同时能快速恢复。侧重点是:(不去真正的请求服务,发生异常再返回),而是直接失败。
- 监控:Hystrix可以实时监控运行指标和配置的变化,提供近实时的监控、报警、运维控制。
- 回退机制:fallback,当请求失败、超时、被拒绝,或当断路器被打开时,执行回退逻辑。回退逻辑我们自定义,提供优雅的服务降级。
- 自我修复:断路器打开一段时间后,会自动进入“半开”状态,可以进行打开,关闭,半开状态的转换。前面有介绍。
3 Hystrix异常机制和处理
Hystrix的异常处理中,有5种出错的情况下会被fallback所截获,从而触发fallback,这些情况是:
- FAILURE:执行失败,抛出异常。
- TIMEOUT:执行超时。
- SHORT_CIRCUITED:断路器打开。
- THREAD_POOL_REJECTED:线程池拒绝。
- SEMAPHORE_REJECTED:信号量拒绝。
有一种类型的异常是不会触发fallback且不会被计数进入熔断的,它是BAD_REQUEST,会抛出HystrixBadRequestException,这种异常一般对应的是由非法参数或者一些非系统异常引起的,对于这类异常可以根据响应创建对应的异常进行异常封装或者直接处理。
当使用包含Ribbon客户端的Hystrix命令时,您需要确保您的Hystrix超时配置为长于配置的Ribbon超时,包括可能进行的任何潜在的重试。例如,如果您的Ribbon连接超时为一秒钟,并且Ribbon客户端可能会重试该请求三次,那么您的Hystrix超时应该略超过三秒钟。
4 Hystrix常见配置
- 隔离策略
#thread 通过线程数量来限制并发请求数,可以提供额外的保护,但有一定的延迟。一般用于网络调用
#semaphore 通过semaphore count来限制并发请求数,适用于无网络的高并发请求
# 默认是Thread, 可选Thread|Semaphore
hystrix.command.default.execution.isolation.strategy
- 命令执行超时时间
#默认1000ms
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
- 执行是否启用超时
#默认启用true
hystrix.command.default.execution.timeout.enabled
- 发生超时是是否中断
#默认启用true
hystrix.command.default.execution.isolation.thread.interruptOnTimeout
- 最大并发请求数
#默认10,该参数当使用ExecutionIsolationStrategy.SEMAPHORE策略时才有效。如果达到最大并发请求数,请求会被拒绝。理论上选择semaphore size的原则和选择thread size一致,但选用semaphore时每次执行的单元要比较小且执行速度快(ms级别),否则的话应该用thread。semaphore应该占整个容器(tomcat)的线程池的一小部分。
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests
在真实的应用过程中,一般会对超时时间、线程池大小、信号量等进行修改,具体要结合业务进行分析,默认Hystrix的超时时间为1秒,但在实际的运用过程中。发现1秒有些过短,通常会设置5~10秒左右,对于一些需要同步文件上传等业务则会更长,如果配置了Ribbon的时间,其超过时间也需要和Ribbon的时间配合实用,一般情况下Ribbon的时间应短于Hystrix超时时间。
Hystrix官方地址:https://github.com/Netflix/Hystrix/wiki/Configuration
5 Hystrix整合Feign
第一步,在Feign中,默认是自带Hystrix的功能的,在很老的版本中默认是打开的,从最近的几个版本开始默认被关闭了,所以需要自己通过配置文件打开它。
feign.hystrix.enabled=true
第二步,定义接口,添加fallback属性,在服务熔断的时候返回fallback类中的内容
@FeignClient(name = "user-provider",fallback = UserServiceFallback.class)
public interface UserService {
@RequestMapping(value = "/getById",method = RequestMethod.GET)
public String getById(Integer id);
}
第三步,创建降级fallback类,实现接口
package com.mashibing.UserConsumer;
import java.util.Map;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
@Component
public class UserServiceFallback implements UserService{
/* 出错则调用该方法返回友好错误 */
@Override
public String getById(Integer id) {
return "用户不存在!";
}
}
6 码农洞见
点击关注『码农洞见』,洞见就在其中。