SpringCloud-Hystrix源码分析

Hystrix实现核心

  • 可配置化的降级策略
    • 信号量、线程实现资源隔离,超时降级,熔断降级
    • HystrixCommandProperty
  • 可以识别的降级边界
    • @HystrixCommand
    • HystrixCommand抽象类
  • 数据采集
    • 如何触发熔断-> 如何采集数据 -> 如何统计数据
    • 信号量 ,最大并发数
  • 行为干预 :触发降级之后对正常业务产生影响
  • 结果干预:fallBack
  • 自动恢复:处于熔断状态会每个5秒尝试恢复

Hystrix熔断的@HystrixCommand注解,是通过HystrixCommandAspect这个切面来处理的。

其中我们关注@Around注解声明的方法,它针对于请求合并,以及降级的注解进行代理。这里我们重点针对HystrixCommand这个注解进行详细分析。

  • getMethodFromTarget 获取目标方法信息

  • MetaHolder metaHolder = metaHolderFactory.create(joinPoint); 获取元数据,比如调用方法, HystrixProperty注解数据、方法参数等

  • HystrixCommandFactory.getInstance().create 获取调用者,它持有一个命令对象,并且可 以在合适的时候通过这个命令对象完成具体的业务逻辑

  • execute,执行命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Around("hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()")
public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable {
Method method = getMethodFromTarget(joinPoint);
Validate.notNull(method, "failed to get method from joinPoint: %s", joinPoint);
if (method.isAnnotationPresent(HystrixCommand.class) && method.isAnnotationPresent(HystrixCollapser.class)) {
throw new IllegalStateException("method cannot be annotated with HystrixCommand and HystrixCollapser " +
"annotations at the same time");
}
MetaHolderFactory metaHolderFactory = META_HOLDER_FACTORY_MAP.get(HystrixPointcutType.of(method));
MetaHolder metaHolder = metaHolderFactory.create(joinPoint);
HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder);
ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ?
metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType();

Object result;
try {
if (!metaHolder.isObservable()) {
result = CommandExecutor.execute(invokable, executionType, metaHolder);
} else {
result = executeObservable(invokable, executionType, metaHolder);
}
} catch (HystrixBadRequestException e) {
throw e.getCause();
} catch (HystrixRuntimeException e) {
throw hystrixRuntimeExceptionToThrowable(metaHolder, e);
}
return result;
}