微服务组件--限流框架Spring Cloud Hystrix分析( 二 )

Hystrix源码总结1.采用了AOP的方式来对方法进行了增强,
2.采用了大量的RxJava响应式编程,利用了Future+线程池的方法进行了大量的异步
3.涉及到了滑动窗口的设计,来进行统计失败率
Hystrix源码分析【1】分析注解@EnableCircuitBreaker是如何开启断路器功能
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@Import(EnableCircuitBreakerImportSelector.class)public @interface EnableCircuitBreaker {}//注解说明:注释以启用断路器实现//但实际上只是导入了EnableCircuitBreakerImportSelector类【2】深入分析EnableCircuitBreakerImportSelector类做了什么
//会发现什么都没做 , 只是将环境变量中的某个值设置为true@Order(Ordered.LOWEST_PRECEDENCE - 100)public class EnableCircuitBreakerImportSelector extends SpringFactoryImportSelector<EnableCircuitBreaker> {@Overrideprotected boolean isEnabled() {return getEnvironment().getProperty("spring.cloud.circuit.breaker.enabled",Boolean.class, Boolean.TRUE);}}【3】分析SpringBoot自动装配会导入什么
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\org.springframework.cloud.netflix.hystrix.HystrixAutoConfiguration,\org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerAutoConfiguration,\org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfigurationorg.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration//该类会比较重要【4】分析HystrixCircuitBreakerConfiguration类做了什么
@Configuration(proxyBeanMethods = false)public class HystrixCircuitBreakerConfiguration {//这个看名字就很重要,初始化AOP的拦截@Beanpublic HystrixCommandAspect hystrixCommandAspect() {return new HystrixCommandAspect();}@Beanpublic HystrixShutdownHook hystrixShutdownHook() {return new HystrixShutdownHook();}@Beanpublic HasFeatures hystrixFeature() {return HasFeatures.namedFeatures(new NamedFeature("Hystrix", HystrixCommandAspect.class));}private class HystrixShutdownHook implements DisposableBean {@Overridepublic void destroy() throws Exception {// Just call Hystrix to reset thread pool etc.Hystrix.reset();}}}【5】分析HystrixCommandAspect类在做了什么
//先是定义了两个切入点@Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand)")public void hystrixCommandAnnotationPointcut() {}@Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser)")public void hystrixCollapserAnnotationPointcut() {}//定义切面@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(...);}MetaHolderFactory metaHolderFactory = META_HOLDER_FACTORY_MAP.get(HystrixPointcutType.of(method));//metaholder中保存了很多和切点相关的信息,说白了就是解析注解获得上面的信息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) {...} catch (HystrixRuntimeException e) {...}return result;}【5.1】模式分析---分析MetaHolder的构成
public MetaHolder create(final ProceedingJoinPoint joinPoint) {Method method = getMethodFromTarget(joinPoint);Object obj = joinPoint.getTarget();Object[] args = joinPoint.getArgs();Object proxy = joinPoint.getThis();return create(proxy, method, obj, args, joinPoint);}private static class CommandMetaHolderFactory extends MetaHolderFactory {@Overridepublic MetaHolder create(Object proxy, Method method, Object obj, Object[] args, final ProceedingJoinPoint joinPoint) {HystrixCommand hystrixCommand = method.getAnnotation(HystrixCommand.class);ExecutionType executionType = ExecutionType.getExecutionType(method.getReturnType());MetaHolder.Builder builder = metaHolderBuilder(proxy, method, obj, args, joinPoint);if (isCompileWeaving()) {builder.ajcMethod(getAjcMethodFromTarget(joinPoint));}return builder.defaultCommandKey(method.getName()).hystrixCommand(hystrixCommand).observableExecutionMode(hystrixCommand.observableExecutionMode()).executionType(executionType).observable(ExecutionType.OBSERVABLE == executionType).build();}}public enum ExecutionType {ASYNCHRONOUS,SYNCHRONOUS,OBSERVABLE;//所以根据我们的基本使用可以判断是SYNCHRONOUS,同步模式public static ExecutionType getExecutionType(Class<?> type) {if (Future.class.isAssignableFrom(type)) {return ExecutionType.ASYNCHRONOUS;} else if (Observable.class.isAssignableFrom(type)) {return ExecutionType.OBSERVABLE;} else {return ExecutionType.SYNCHRONOUS;}}}

推荐阅读