【一起学源码-微服务】Hystrix 源码一:Hystrix基础原理与Demo搭建 (2)

Hystrix基础原理.jpg

Hystrix Demo搭建

Demo工程还是使用之前的项目,git地址:https://github.com/barrywangmeng/spring-cloud-learn

eureka-server:注册中心
serviceA: 提供对外接口
serviceB: 通过feign调用serviceA接口

在serviceB项目中添加hystrix相关pom依赖及配置,这里就不列出来了,小伙伴们可以直接下载这个项目看一下。

接着就是改造对serviceA调用的FeignClient:

image.png

image.png

我们可以调整serviceB中feign调用超时时间配置类模拟触发Hystrix降级逻辑:

image.png

Hystrix源码阅读及调试说明

我们在调试的过程中,为了方便走正常不降级逻辑的debug调试,特地会修改feign及hystrix的超时时间。

因为hystrix中大量使用了响应式编程(rxJava),代码中包含大量的观察者模式设计,各种回调函数糅杂在一起,所以代码显得很难懂。

这里我们不纠结更多的rxJava源码,为了调试,每个回调方法都会打上断点。

关于Hystrix daboard相关的内容这里也不会讲解,实际项目中会使用其他第三方组件来做服务监控,这里不做更多研究。

Hystrix入口程序初探

之前我们讲过,如果不配置feign.hystrix.enabled:true这个配置的话,默认用的是DefaultTargeter, 配置了的话就改变为HystrixTargeter。

我们来看看HystrixTargeter.target()方法:

class HystrixTargeter implements Targeter { @Override public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context, Target.HardCodedTarget<T> target) { if (!(feign instanceof feign.hystrix.HystrixFeign.Builder)) { return feign.target(target); } // 里面包含encoder、decoder等feign的组件信息 feign.hystrix.HystrixFeign.Builder builder = (feign.hystrix.HystrixFeign.Builder) feign; // factory.getName: serviceA 返回的setterFactory 是null SetterFactory setterFactory = getOptional(factory.getName(), context, SetterFactory.class); if (setterFactory != null) { builder.setterFactory(setterFactory); } // 获取设置的feignClient的fallback属性 Class<?> fallback = factory.getFallback(); if (fallback != void.class) { return targetWithFallback(factory.getName(), context, target, builder, fallback); } // 获取设置的feignClient的fallbackFactory属性 Class<?> fallbackFactory = factory.getFallbackFactory(); if (fallbackFactory != void.class) { // 配置了降级factory的话,直接进入这个逻辑 return targetWithFallbackFactory(factory.getName(), context, target, builder, fallbackFactory); } return feign.target(target); } private <T> T targetWithFallbackFactory(String feignClientName, FeignContext context, Target.HardCodedTarget<T> target, HystrixFeign.Builder builder, Class<?> fallbackFactoryClass) { FallbackFactory<? extends T> fallbackFactory = (FallbackFactory<? extends T>) getFromContext("fallbackFactory", feignClientName, context, fallbackFactoryClass, FallbackFactory.class); // 调用我们自定义的fallback工厂中的create方法 Object exampleFallback = fallbackFactory.create(new RuntimeException()); Assert.notNull(exampleFallback, String.format( "Incompatible fallbackFactory instance for feign client %s. Factory may not produce null!", feignClientName)); // target.type() 就是ServiceAFeignClient 这个feignClient接口的名称 这里就是做些判断 if (!target.type().isAssignableFrom(exampleFallback.getClass())) { throw new IllegalStateException( String.format( "Incompatible fallbackFactory instance for feign client %s. Factory produces instances of '%s', but should produce instances of '%s'", feignClientName, exampleFallback.getClass(), target.type())); } // 执行HystrixFeign中的target方法 return builder.target(target, fallbackFactory); } }

我们设置的这个FallbackFactory负责在每次超时、拒绝(线程池满)、异常的时候,create()方法返回一个降级机制的对象

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwydfx.html