Hystrix 源码解读

1,430 阅读1分钟

入口

image.png

@EnableCircuitBreaker 这注解也能开启Hystrix的相关功能

image.png

image.png 其中读取spring.factories哪个文件的入口在此 org.springframework.cloud.commons.util.SpringFactoryImportSelector#selectImports

public String[] selectImports(AnnotationMetadata metadata) {
   if (!isEnabled()) {
      return new String[0];
   }
   AnnotationAttributes attributes = AnnotationAttributes.fromMap(
         metadata.getAnnotationAttributes(this.annotationClass.getName(), true));

   Assert.notNull(attributes, "No " + getSimpleName() + " attributes found. Is "
         + metadata.getClassName() + " annotated with @" + getSimpleName() + "?");

   // 因为是EnableCircuitBreaker这个注解读取的是META-INF/spring.factories 中org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration  这个配置
   List<String> factories = new ArrayList<>(new LinkedHashSet<>(SpringFactoriesLoader
         .loadFactoryNames(this.annotationClass, this.beanClassLoader)));

   if (factories.isEmpty() && !hasDefaultFactory()) {
      throw new IllegalStateException("Annotation @" + getSimpleName()
            + " found, but there are no implementations. Did you forget to include a starter?");
   }

   if (factories.size() > 1) {
      // there should only ever be one DiscoveryClient, but there might be more than
      // one factory
      log.warn("More than one implementation " + "of @" + getSimpleName()
            + " (now relying on @Conditionals to pick one): " + factories);
   }

   return factories.toArray(new String[factories.size()]);
}

image.png 现在知道对应配置是怎么自动读取的吧!

相关源码分析

image.png

image.png 核心逻辑com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect#methodsAnnotatedWithHystrixCommand

@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() != null ? e.getCause() : e;
    } catch (HystrixRuntimeException e) {
        throw hystrixRuntimeExceptionToThrowable(metaHolder, e);
    }
    return result;
}

封装

image.png

image.png

image.png 默认为 SYNCHRONOUS image.png

image.png

image.png 下面是Rxjava的相关编程,个人不是很熟

执行成功的逻辑

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png 这里就是调用的逻辑,由于是使用reactor模式的调用,我也做不了详细的解释,惭愧啊!

推荐相关的源码解释:www.iocoder.cn/categories/…