文章目录
一、Hystrix介绍
Hystrix能够在依赖服务失效的情况下,通过隔离系统依赖服务的方式,防止服务级联失败;同时 Hystrix 提供失败回滚机制,使系统能够更快地从异常中恢复
二、预备知识
1、@HystrixCommand详解
- groupKey:分组名称,Hystrix会根据不同的分组来统计命令的告警及仪表盘信息,默认注解方法类的名称;
- commandKey:命令名称,用于区分不同的命令;
- threadPoolKey:线程池名称,用于划分线程池,线程池键用来指定命令执行的HystrixThreadPool;
- fallbackMethod:指定服务降级处理方法,定义回退方法的名称,此方法必须和hystrix的执行方法在相同类中;
- ignoreExceptions:定义忽略某些异常,不发生服务降级;
- commandProperties:配置自定义hystrix命令的参数;
一般来说,对于 HystrixCommand 的配置,仅需要关注 fallbackMethod 方法,当然如果对命令和线程有特定需要,可以进行额外的配置。
2、@HystrixCollapser的常用属性
微服务系统中的服务间通信,需要通过远程调用来实现,随着调用次数越来越多,占用线程资源也会越来越多。Hystrix中提供了@HystrixCollapser用于合并请求,从而达到减少通信消耗及线程数量的效果,使用@HystrixCollapser实现请求合并,所有对某个接口的的多次调用都会转化为对该接口的单次调用。
- batchMethod:用于设置请求合并的方法;
- collapserProperties:请求合并属性,用于控制实例属性;
- timerDelayInMilliseconds:collapserProperties中的属性,用于控制每隔多少时间的请求合并为一次请求;
3、Hystrix的请求缓存
当系统并发量越来越大时,我们需要使用缓存来优化系统,达到减轻并发请求线程数,提供响应速度的效果。
- @CacheResult:开启缓存,默认所有参数作为缓存的key,cacheKeyMethod可以通过返回String类型的方法指定key
- @CacheKey:指定缓存的key,可以指定参数或指定参数中的属性值为缓存key,cacheKeyMethod还可以通过返回String类型的方法指定;
- @CacheRemove:移除缓存,需要指定commandKey。
@CacheResult(cacheKeyMethod = "getCacheKey")
@HystrixCommand(fallbackMethod = "getDefaultUser", commandKey = "getUserCache")
在缓存使用过程中,我们需要在每次使用缓存的请求前后对HystrixRequestContext进行初始化和关闭,否则会出现如下异常:
建议使用:@Cleanup
@Cleanup HystrixRequestContext context = HystrixRequestContext.initializeContext();
4、Hystrix的配置
4.1、全局配置
# 开启Feign下面的Hystrix功能
feign.hystrix.enabled=true
# 是否开启服务降级
hystrix.command.default.fallback.enabled=true
# 全局超时
hystrix.command.default.execution.timeout.enabled=true
# 超时时间
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1000
# 超时以后终止线程
hystrix.command.default.execution.isolation.thread.interruptOnTimeout=true
# 取消的时候终止线程
hystrix.command.default.execution.isolation.thread.interruptOnFutureCancel=true
# 熔断的前提条件(请求的数量),在一定的时间窗口内,请求达到5个以后,才开始进行熔断判断
hystrix.command.default.circuitBreaker.requestVolumeThreshold=5
# 超过50%的失败请求,则熔断开关开启
hystrix.command.default.circuitBreaker.errorThresholdPercentage=50
# 当熔断开启以后,经过多少秒再进入半开状态
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=15000
# 配置时间窗口
hystrix.command.default.metrics.rollingStats.timeInMilliseconds=20000
hystrix.command.default.circuitBreaker.enabled=true
# 强制开启熔断开关
hystrix.command.default.circuitBreaker.forceOpen=false
# 强制关闭熔断开关
hystrix.command.default.circuitBreaker.forceClosed=false
参数说明英文地址:https://github.com/Netflix/Hystrix/wiki/Configuration
4.2、服务方法的配置
使用@HystrixCommand注解对对应的接口服务进行配置。
参数说明英文地址:https://github.com/Netflix/Hystrix/wiki/Configuration
三、源码解析
1. 实现fallback
1.1 从注解HystrixCommand进入到
2.2、通过HystrixCommand找到HystrixCommandAspect.java


进入create()方法
public HystrixInvokable create(MetaHolder metaHolder) {
HystrixInvokable executable;
if (metaHolder.isCollapserAnnotationPresent()) {
executable = new CommandCollapser(metaHolder);
} else if (metaHolder.isObservable()) {
executable = new GenericObservableCommand(HystrixCommandBuilderFactory.getInstance().create(metaHolder));
} else {
executable = new GenericCommand(HystrixCommandBuilderFactory.getInstance().create(metaHolder));
}
return executable;
}
MetaHolderFactory的构造

再进入到result = CommandExecutor.execute(invokable, executionType, metaHolder);这个execute的方法中:
executionType决定了最终的执行方式,如下
- execute():同步执行,从依赖的服务返回一个单一的结果对象,或是在发生错误的时候抛出异常;
- queue():异步执行,直接返回一个Future对象,其中包含了服务执行结束时要返回的单一结果对象;
- observe():返回Observable对象,它代表了操作的多个结果,他是一个Hot Observable;
- toObservable():同样返回Observable对象,也代表了操作的多个结果,但其返回的是一个Cold Observable;
进入execute()方法


2. 实现requestCache的存储和获取
HystrixRequestCache的定义如下:通过ConcurrentHashMap来保证线程安全
根据AbstractCommand的构造函数,可以发现requestCache的构造方法:
HystrixPlugins获取concurrencyStrategy并发策略,
从而实例化了HystrixRequestCache实例requestCache
未完待续。。。