SpringClouHystrix运行流程及源码

断路器作用:熔断、隔离和降级
熔断:本质是对原子Boolean的判断和properties中的一堆阈值判断
隔离:通过线程池和信号量实现目标为服务调用之间的互不干扰,map
降级:目标服务器嘎嘣儿了或网络IO超时了,从定义的fallback静态缓存中获取返回数据,就是出错了,别整那么难看,保证后端服务不要大面积受到影响而瘫痪
在这里插入图片描述

源码按照三部分来分析:配置、执行、关闭

第一部分源码:断路器的自动装配

自动装配是springboot中的基础知识,我之前的文章中有想学习的执行流程

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({
    
    Hystrix.class})
@ConditionalOnProperty(name = "spring.cloud.circuitbreaker.hystrix.enabled",
        matchIfMissing = true)
public class HystrixCircuitBreakerAutoConfiguration {
    
    

    @Autowired(required = false)
    private List<Customizer<HystrixCircuitBreakerFactory>> customizers = new ArrayList<>();


    //熔断器工厂类
    @Bean
    @ConditionalOnMissingBean(CircuitBreakerFactory.class)
    public CircuitBreakerFactory hystrixCircuitBreakerFactory() {
    
    
        HystrixCircuitBreakerFactory factory = new HystrixCircuitBreakerFactory();
        customizers.forEach(customizer -> customizer.customize(factory));
        return factory;
    }

}

//------------------------------------------------------------------------
//通过工厂创建熔断器
public class HystrixCircuitBreakerFactory extends
        CircuitBreakerFactory<HystrixCommand.Setter, org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerFactory.HystrixConfigBuilder> {
    
    

    private Function<String, HystrixCommand.Setter> defaultConfiguration = id -> HystrixCommand.Setter
            .withGroupKey(
                    HystrixCommandGroupKey.Factory.asKey(getClass().getSimpleName()))
            .andCommandKey(HystrixCommandKey.Factory.asKey(id));

    //保存默认配置
    public void configureDefault(
            Function<String, HystrixCommand.Setter> defaultConfiguration) {
    
    
        this.defaultConfiguration = defaultConfiguration;
    }

    public org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerFactory.HystrixConfigBuilder configBuilder(String id) {
    
    
        return new org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerFactory.HystrixConfigBuilder(id);
    }

    //核心处理方法
    public org.springframework.cloud.netflix.hystrix.HystrixCircuitBreaker create(String id) {
    
    
        Assert.hasText(id, "A CircuitBreaker must have an id.");
        HystrixCommand.Setter setter = getConfigurations().computeIfAbsent(id,
                defaultConfiguration);//获取Hystrix执行命令的设置
                //创建熔断管理器【重要】
        return new HystrixCircuitBreaker(setter);
    }

    public static class HystrixConfigBuilder
            extends AbstractHystrixConfigBuilder<HystrixCommand.Setter> {
    
    

        public HystrixConfigBuilder(String id) {
    
    
            super(id);
        }

        //构建熔断器的初始化配置
        @Override
        public HystrixCommand.Setter build() {
    
    
            //操作组
            return HystrixCommand.Setter.withGroupKey(getGroupKey())
                    //操作key
                    .andCommandKey(getCommandKey())
                    //这里的一些重要配置
                    //1.默认错误与之百分比50%打开断路器
                    //private static final Integer default_circuitBreakerErrorThresholdPercentage = 50;
                    //2.默认请求超时时间
                    //private static final Integer default_executionTimeoutInMilliseconds = 1000;
                    //3.隔离策略
                    // public static enum ExecutionIsolationStrategy {
    
    
                    //         线程池(默认)   信号量
                    //        THREAD, SEMAPHORE
                    //    }
                    //4.默认隔离策略(线程)
                    //private static final ExecutionIsolationStrategy default_executionIsolationStrategy = ExecutionIsolationStrategy.THREAD;
                    //5.熔断请求线程阈值  20
                    //circuitBreakerRequestVolumeThreshold
                    //6.熔断是否开启状态 TRUE
                    //circuitBreakerEnabled
                    .andCommandPropertiesDefaults(getCommandPropertiesSetter());

            //可使用注解配置隔离模式
                    /*
                    *
                    * @HystrixCommand(fallbackMethod = "fallbackMethod",
                           commandProperties = {
                            // 设置隔离策略,THREAD 表示线程池 SEMAPHORE:信号池隔离
                          @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
                            // 当隔离策略选择信号池隔离的时候,用来设置信号池的大小(最大并发数)
                        @HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "10"),
                        }
                      )
                    *  */


        }

    }

}







//-------------------------------------
//断路器的实现方式1
public class HystrixCircuitBreaker implements CircuitBreaker {
    
    

    /*  Setter内部的配置属性
       //groupKey是执行目标方法所在的类名
    *  protected final HystrixCommandGroupKey groupKey;
    * 	//对应方法名
        protected HystrixCommandKey commandKey;
        * //线程池的key 即某一个服务应用  最终在map中实现线程池的应用隔离
        * //是执行目标方法所在的类名
        protected HystrixThreadPoolKey threadPoolKey;
        protected HystrixCommandProperties.Setter commandPropertiesDefaults;
        protected HystrixThreadPoolProperties.Setter threadPoolPropertiesDefaults;
    *   */

    private HystrixCommand.Setter setter;

    public HystrixCircuitBreaker(HystrixCommand.Setter setter) {
    
    
        this.setter = setter;
    }

    @Override
    public <T> T run(Supplier<T> toRun, Function<Throwable, T> fallback) {
    
    

        HystrixCommand<T> command = new HystrixCommand<T>(setter) {
    
    
            //具体操作的执行
            @Override
            protected T run() throws Exception {
    
    
                return toRun.get();
            }

            //获取失败的回退方法
            @Override
            protected T getFallback() {
    
    
                return fallback.apply(getExecutionException());
            }
        };
        //具体的执行处理
        return command.execute();
    }

}
//断路器的实现2
//断路器实现的另一种方式,没错,该接口和上面的类名一样
//可以理解为通过一堆判断(度量结果和配置的阈值等等)当前请求是否可以通过....
//原子布尔变量保存中断器是否开关
//中断器的本质就是Boolean值的判断
public interface HystrixCircuitBreaker {
    
    
    //每个请求即将HystrixCommand都会判断是否允许连接
    boolean allowRequest();

    //断路器是否打开
    boolean isOpen();

    //半开关状态时成功执行请求时调用
    void markSuccess();


    public static class Factory {
    
    
        //熔断器缓存,如指定资源打开了熔断器,则不可访问。缓存状态
        private static ConcurrentHashMap<String, HystrixCircuitBreaker> circuitBreakersByCommand = new ConcurrentHashMap<String, HystrixCircuitBreaker>();

        //为指定的CommandKey创建熔断器
        public static HystrixCircuitBreaker getInstance(HystrixCommandKey key, HystrixCommandGroupKey group, HystrixCommandProperties properties, HystrixCommandMetrics metrics) {
    
    
            //查询缓存
            HystrixCircuitBreaker previouslyCached = circuitBreakersByCommand.get(key.name());
            if (previouslyCached != null) {
    
    
                return previouslyCached;
            }
            //缓存未命中 进行熔断器初始化
            HystrixCircuitBreaker cbForCommand = circuitBreakersByCommand.putIfAbsent(key.name(), new HystrixCircuitBreakerImpl(key, group, properties, metrics));
            if (cbForCommand == null) {
    
    
                return circuitBreakersByCommand.get(key.name());
            } else {
    
    
                return cbForCommand;
            }
        }

        public static HystrixCircuitBreaker getInstance(HystrixCommandKey key) {
    
    
            return circuitBreakersByCommand.get(key.name());
        }

        //清除所有断路器
        static void reset() {
    
    
            circuitBreakersByCommand.clear();
        }
    }

    //内部类  HystrixCircuitBreaker断路器的实现类
    class HystrixCircuitBreakerImpl implements HystrixCircuitBreaker {
    
    
        //熔断器的配置属性  如超时时间  请求失败阈值等
        private final HystrixCommandProperties properties;
        //度量统计 没有统计如何统计阈值呢?
        private final HystrixCommandMetrics metrics;
        //中断开关,默认 关闭
        private AtomicBoolean circuitOpen = new AtomicBoolean(false);
        //半开时的尝试
        private AtomicLong circuitOpenedOrLastTestedTime = new AtomicLong();

        protected HystrixCircuitBreakerImpl(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixCommandProperties properties, HystrixCommandMetrics metrics) {
    
    
            this.properties = properties;
            this.metrics = metrics;
        }

        //半开关时调用除尘工的标记
        public void markSuccess() {
    
    
            //判断中断器状态  默认开启的
            if (circuitOpen.get()) {
    
    
                if (circuitOpen.compareAndSet(true, false)) {
    
    
                    //度量重置
                    metrics.resetStream();
                }
            }
        }

        //允许访问的控制
        @Override
        public boolean allowRequest() {
    
    
            //强制性中断配置
            if (properties.circuitBreakerForceOpen().get()) {
    
    
                return false;
            }
            //强制性中断关闭
            if (properties.circuitBreakerForceClosed().get()) {
    
    
                isOpen();
                //不启动中断器
                return true;
            }
            return !isOpen() || allowSingleTest();
        }

        //半开状态下测试是否允许关闭中断器
        public boolean allowSingleTest() {
    
    
            long timeCircuitOpenedOrWasLastTested = circuitOpenedOrLastTestedTime.get();
            if (circuitOpen.get() && System.currentTimeMillis() > timeCircuitOpenedOrWasLastTested + properties.circuitBreakerSleepWindowInMilliseconds().get()) {
    
    
                if (circuitOpenedOrLastTestedTime.compareAndSet(timeCircuitOpenedOrWasLastTested, System.currentTimeMillis())) {
    
    
                    return true;
                }
            }
            return false;
        }

        //判断是否开启
        @Override
        public boolean isOpen() {
    
    
            if (circuitOpen.get()) {
    
    
                return true;
            }
            HystrixCommandMetrics.HealthCounts health = metrics.getHealthCounts();
            if (health.getTotalRequests() < properties.circuitBreakerRequestVolumeThreshold().get()) {
    
    
                return false;
            }
            if (health.getErrorPercentage() < properties.circuitBreakerErrorThresholdPercentage().get()) {
    
    
                return false;
            } else {
    
    
                if (circuitOpen.compareAndSet(false, true)) {
    
    
                    circuitOpenedOrLastTestedTime.set(System.currentTimeMillis());
                    return true;
                } else {
    
    
                    return true;
                }
            }
        }
    }

    //内部类  熔断器的空实现
    class NoOpCircuitBreaker implements HystrixCircuitBreaker {
    
    

        @Override
        public boolean allowRequest() {
    
    
            return true;
        }

        @Override
        public boolean isOpen() {
    
    
            return false;
        }

        @Override
        public void markSuccess() {
    
    

        }

    }

}


第二部分:执行hystrixCommand命令

//执行模式
public enum ExecutionType {
    
    
    //异步处理
    ASYNCHRONOUS,
    //同步处理
    SYNCHRONOUS,
    //响应式处理
    OBSERVABLE;

    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;
        }
    }
}



//命令执行,即hystrix的具体执行操作
public class CommandExecutor {
    
    
    //根据指定的执行类型调用方法
    public static Object execute(HystrixInvokable invokable, ExecutionType executionType, MetaHolder metaHolder) throws RuntimeException {
    
    
        Validate.notNull(invokable);
        Validate.notNull(metaHolder);
        //类型判断
        switch (executionType) {
    
    
            case SYNCHRONOUS: {
    
    
                return castToExecutable(invokable, executionType).execute();
            }
            case ASYNCHRONOUS: {
    
    
                HystrixExecutable executable = castToExecutable(invokable, executionType);
                if (metaHolder.hasFallbackMethodCommand()
                        && ExecutionType.ASYNCHRONOUS == metaHolder.getFallbackExecutionType()) {
    
    
                    return new FutureDecorator(executable.queue());
                }
                return executable.queue();
            }
            case OBSERVABLE: {
    
    
                HystrixObservable observable = castToObservable(invokable);
                return ObservableExecutionMode.EAGER == metaHolder.getObservableExecutionMode() ? observable.observe() : observable.toObservable();
            }
            default:
                throw new RuntimeException("unsupported execution type: " + executionType);
        }
    }

    private static HystrixExecutable castToExecutable(HystrixInvokable invokable, ExecutionType executionType) {
    
    
        if (invokable instanceof HystrixExecutable) {
    
    
            return (HystrixExecutable) invokable;
        }
        throw new RuntimeException("Command should implement " + HystrixExecutable.class.getCanonicalName() + " interface to execute in: " + executionType + " mode");
    }

    private static HystrixObservable castToObservable(HystrixInvokable invokable) {
    
    
        if (invokable instanceof HystrixObservable) {
    
    
            return (HystrixObservable) invokable;
        }
        throw new RuntimeException("Command should implement " + HystrixObservable.class.getCanonicalName() + " interface to execute in observable mode");
    }

}





//该抽象父类整合了HystrixCommand在执行的时候所有相关属性
//封装熔断器的基本方法
abstract class AbstractCommand<R> implements HystrixInvokableInfo<R>, HystrixObservable<R> {
    
    
    private static final Logger logger = LoggerFactory.getLogger(AbstractCommand.class);
    //中断器
    protected final com.netflix.hystrix.HystrixCircuitBreaker circuitBreaker;
    //线程池
    protected final com.netflix.hystrix.HystrixThreadPool threadPool;
    //线程池key
    protected final HystrixThreadPoolKey threadPoolKey;
    //中断器配置  如超时时间等
    protected final HystrixCommandProperties properties;

    //超时状态
    protected enum TimedOutStatus {
    
    
        //不执行  已完成  执行超时
        NOT_EXECUTED, COMPLETED, TIMED_OUT
    }

    //命令状态
    protected enum CommandState {
    
    
        //未启动       创建可观察连                  执行的用户代码         取消订阅       结束
        NOT_STARTED, OBSERVABLE_CHAIN_CREATED, USER_CODE_EXECUTED, UNSUBSCRIBED, TERMINAL
    }

    //线程状态
    protected enum ThreadState {
    
    
        //不使用线程         启动完毕   取消订阅       结束
        NOT_USING_THREAD, STARTED, UNSUBSCRIBED, TERMINAL
    }

    //度量信息
    protected final HystrixCommandMetrics metrics;


    //响应式处理
    private Observable<R> applyHystrixSemantics(final AbstractCommand<R> _cmd) {
    
    
        executionHook.onStart(_cmd);
        //判断中断器是否打开,即请求是否可以执行
        if (circuitBreaker.allowRequest()) {
    
    
            //信号量
            final TryableSemaphore executionSemaphore = getExecutionSemaphore();
            final AtomicBoolean semaphoreHasBeenReleased = new AtomicBoolean(false);
            final Action0 singleSemaphoreRelease = new Action0() {
    
    
                @Override
                public void call() {
    
    
                    if (semaphoreHasBeenReleased.compareAndSet(false, true)) {
    
    
                        //释放处理
                        executionSemaphore.release();
                    }
                }
            };
            //异常处理
            final Action1<Throwable> markExceptionThrown = new Action1<Throwable>() {
    
    
                @Override
                public void call(Throwable t) {
    
    
                    eventNotifier.markEvent(HystrixEventType.EXCEPTION_THROWN, commandKey);
                }
            };
            //是否可获得信号量
            if (executionSemaphore.tryAcquire()) {
    
    
                try {
    
    
                    //获得调用的开始时间
                    executionResult = executionResult.setInvocationStartTime(System.currentTimeMillis());
                    return executeCommandAndObserve(_cmd)
                            .doOnError(markExceptionThrown)
                            .doOnTerminate(singleSemaphoreRelease)
                            .doOnUnsubscribe(singleSemaphoreRelease);
                } catch (RuntimeException e) {
    
    
                    return Observable.error(e);
                }
            } else {
    
    
                return handleSemaphoreRejectionViaFallback();
            }
        } else {
    
    
            return handleShortCircuitViaFallback();
        }
    }


    private Observable<R> executeCommandAndObserve(final AbstractCommand<R> _cmd) {
    
    
        final HystrixRequestContext currentRequestContext = HystrixRequestContext.getContextForCurrentThread();

        final Action1<R> markEmits = new Action1<R>() {
    
    
            @Override
            public void call(R r) {
    
    
                if (shouldOutputOnNextEvents()) {
    
    
                    executionResult = executionResult.addEvent(HystrixEventType.EMIT);
                    eventNotifier.markEvent(HystrixEventType.EMIT, commandKey);
                }
                if (commandIsScalar()) {
    
    
                    long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();
                    eventNotifier.markCommandExecution(getCommandKey(), properties.executionIsolationStrategy().get(), (int) latency, executionResult.getOrderedList());
                    eventNotifier.markEvent(HystrixEventType.SUCCESS, commandKey);
                    executionResult = executionResult.addEvent((int) latency, HystrixEventType.SUCCESS);
                    circuitBreaker.markSuccess();
                }
            }
        };

        final Action0 markOnCompleted = new Action0() {
    
    
            @Override
            public void call() {
    
    
                if (!commandIsScalar()) {
    
    
                    long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();
                    eventNotifier.markCommandExecution(getCommandKey(), properties.executionIsolationStrategy().get(), (int) latency, executionResult.getOrderedList());
                    eventNotifier.markEvent(HystrixEventType.SUCCESS, commandKey);
                    executionResult = executionResult.addEvent((int) latency, HystrixEventType.SUCCESS);
                    circuitBreaker.markSuccess();
                }
            }
        };
        //失败的会退处理
        final Func1<Throwable, Observable<R>> handleFallback = new Func1<Throwable, Observable<R>>() {
    
    
            @Override
            public Observable<R> call(Throwable t) {
    
    
                //获取异常类型
                Exception e = getExceptionFromThrowable(t);
                executionResult = executionResult.setExecutionException(e);
                if (e instanceof RejectedExecutionException) {
    
    
                    //线程池拒绝
                    return handleThreadPoolRejectionViaFallback(e);
                } else if (t instanceof HystrixTimeoutException) {
    
    
                    //请求超时
                    return handleTimeoutViaFallback();
                } else if (t instanceof HystrixBadRequestException) {
    
    
                    //请求失败
                    return handleBadRequestByEmittingError(e);
                } else {
    
    
                    if (e instanceof HystrixBadRequestException) {
    
    
                        eventNotifier.markEvent(HystrixEventType.BAD_REQUEST, commandKey);
                        return Observable.error(e);
                    }
                    return handleFailureViaFallback(e);
                }
            }
        };
    }

    //执行命令和指定隔离
    private Observable<R> executeCommandWithSpecifiedIsolation(final AbstractCommand<R> _cmd) {
    
    
        //得到隔离策略
        if (properties.executionIsolationStrategy().get() == HystrixCommandProperties.ExecutionIsolationStrategy.THREAD) {
    
    
            return Observable.defer(new Func0<Observable<R>>() {
    
    
                @Override
                public Observable<R> call() {
    
    
                    executionResult = executionResult.setExecutionOccurred();
                    if (!commandState.compareAndSet(CommandState.OBSERVABLE_CHAIN_CREATED, CommandState.USER_CODE_EXECUTED)) {
    
    
                        return Observable.error(new IllegalStateException("execution attempted while in state : " + commandState.get().name()));
                    }

                    metrics.markCommandStart(commandKey, threadPoolKey, HystrixCommandProperties.ExecutionIsolationStrategy.THREAD);
                    if (isCommandTimedOut.get() == TimedOutStatus.TIMED_OUT) {
    
    
                        return Observable.error(new RuntimeException("timed out before executing run()"));
                    }
                    if (threadState.compareAndSet(ThreadState.NOT_USING_THREAD, ThreadState.STARTED)) {
    
    
                        HystrixCounters.incrementGlobalConcurrentThreads();
                        threadPool.markThreadExecution();
                        endCurrentThreadExecutingCommand = Hystrix.startCurrentThreadExecutingCommand(getCommandKey());
                        executionResult = executionResult.setExecutedInThread();
                        try {
    
    
                            //钩子,在代码执行完毕后做一些收尾处理
                            executionHook.onThreadStart(_cmd);
                            executionHook.onRunStart(_cmd);
                            executionHook.onExecutionStart(_cmd);
                            return getUserExecutionObservable(_cmd);
                        } catch (Throwable ex) {
    
    
                            return Observable.error(ex);
                        }
                    } else {
    
    
                        return Observable.error(new RuntimeException("unsubscribed before executing run()"));
                    }
                }
            }).doOnTerminate(new Action0() {
    
    
                @Override
                public void call() {
    
    
                    if (threadState.compareAndSet(ThreadState.STARTED, ThreadState.TERMINAL)) {
    
    
                        handleThreadEnd(_cmd);
                    }
                    if (threadState.compareAndSet(ThreadState.NOT_USING_THREAD, ThreadState.TERMINAL)) {
    
    
                    }
                }
            }).doOnUnsubscribe(new Action0() {
    
    
                @Override
                public void call() {
    
    
                    if (threadState.compareAndSet(ThreadState.STARTED, ThreadState.UNSUBSCRIBED)) {
    
    
                        handleThreadEnd(_cmd);
                    }
                    if (threadState.compareAndSet(ThreadState.NOT_USING_THREAD, ThreadState.UNSUBSCRIBED)) {
    
    
                    }
                }
            }).subscribeOn(threadPool.getScheduler(new Func0<Boolean>() {
    
    
                @Override
                public Boolean call() {
    
    
                    return properties.executionIsolationThreadInterruptOnTimeout().get() && _cmd.isCommandTimedOut.get() == TimedOutStatus.TIMED_OUT;
                }
            }));
        } else {
    
    
            return Observable.defer(new Func0<Observable<R>>() {
    
    
                @Override
                public Observable<R> call() {
    
    
                    executionResult = executionResult.setExecutionOccurred();
                    if (!commandState.compareAndSet(CommandState.OBSERVABLE_CHAIN_CREATED, CommandState.USER_CODE_EXECUTED)) {
    
    
                        return Observable.error(new IllegalStateException("execution attempted while in state : " + commandState.get().name()));
                    }

                    metrics.markCommandStart(commandKey, threadPoolKey, HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE);

                    endCurrentThreadExecutingCommand = Hystrix.startCurrentThreadExecutingCommand(getCommandKey());
                    try {
    
    
                        executionHook.onRunStart(_cmd);
                        executionHook.onExecutionStart(_cmd);
                        return getUserExecutionObservable(_cmd);
                    } catch (Throwable ex) {
    
    
                        return Observable.error(ex);
                    }
                }
            });
        }
    }
    //........


}



//执行命令封装
public abstract class HystrixCommand<R> extends AbstractCommand<R> implements HystrixExecutable<R>, HystrixInvokableInfo<R>, HystrixObservable<R> {
    
    

    //JUC中的原子引用,代表当前正在执行的线程对象
    private final AtomicReference<Thread> executionThread = new AtomicReference<Thread>();
    //JUCBoolean 优雅线程停止操作
    private final AtomicBoolean interruptOnFutureCancel = new AtomicBoolean(false);

    //定义hystrix的具体执行
    //有不同的执行形式 execute   queue   observer
    protected abstract R run() throws Exception;

    //回退方法,即缓存的结果,不需要和真正服务网络IO
    protected R getFallback() {
    
    
        throw new UnsupportedOperationException("No fallback available.");
    }

    //执行请求
    @Override
    final protected Observable<R> getExecutionObservable() {
    
    
        //创建数据响应
        return Observable.defer(new Func0<Observable<R>>() {
    
    
            @Override
            public Observable<R> call() {
    
    
                try {
    
    
                    //请求发送,需将请求转为just可观察对象
                    return Observable.just(run());
                } catch (Throwable ex) {
    
    
                    return Observable.error(ex);
                }
            }
            //订阅处理
        }).doOnSubscribe(new Action0() {
    
    
            @Override
            public void call() {
    
    
                //保存订阅的线程即当前正在执行的线程
                executionThread.set(Thread.currentThread());
            }
        });
    }

    //失败回退的订阅,响应式编程(调用)
    @Override
    final protected Observable<R> getFallbackObservable() {
    
    
        return Observable.defer(new Func0<Observable<R>>() {
    
    
            @Override
            public Observable<R> call() {
    
    
                try {
    
    
                    //调用失败回退的方法
                    return Observable.just(getFallback());
                } catch (Throwable ex) {
    
    
                    //响应错误状态
                    return Observable.error(ex);
                }
            }
        });
    }


    //按照队列的方式具体执行,异步
    public R execute() {
    
    
        try {
    
    
            //异步执行
            return queue().get();
        } catch (Exception e) {
    
    
            throw Exceptions.sneakyThrow(decomposeException(e));
        }
    }

    //异步的处理队列
    public Future<R> queue() {
    
    
        final Future<R> delegate = toObservable().toBlocking().toFuture();
        final Future<R> f = new Future<R>() {
    
    
            @Override
            public boolean cancel(boolean mayInterruptIfRunning) {
    
    
                if (delegate.isCancelled()) {
    
    
                    return false;
                }
                if (HystrixCommand.this.getProperties().executionIsolationThreadInterruptOnFutureCancel().get()) {
    
    
                    interruptOnFutureCancel.compareAndSet(false, mayInterruptIfRunning);
                }
                final boolean res = delegate.cancel(interruptOnFutureCancel.get());
                if (!isExecutionComplete() && interruptOnFutureCancel.get()) {
    
    
                    final Thread t = executionThread.get();
                    if (t != null && !t.equals(Thread.currentThread())) {
    
    
                        t.interrupt();
                    }
                }
                return res;
            }

            @Override
            public boolean isCancelled() {
    
    
                return delegate.isCancelled();
            }

            @Override
            public boolean isDone() {
    
    
                return delegate.isDone();
            }

            @Override
            public R get() throws InterruptedException, ExecutionException {
    
    
                return delegate.get();
            }

            @Override
            public R get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
    
    
                return delegate.get(timeout, unit);
            }
        };
        if (f.isDone()) {
    
    
            try {
    
    
                f.get();
                return f;
            } catch (Exception e) {
    
    
                Throwable t = decomposeException(e);
                if (t instanceof HystrixBadRequestException) {
    
    
                    return f;
                } else if (t instanceof HystrixRuntimeException) {
    
    
                    HystrixRuntimeException hre = (HystrixRuntimeException) t;
                    switch (hre.getFailureType()) {
    
    
                        case COMMAND_EXCEPTION:
                        case TIMEOUT:
                            return f;
                        default:
                            throw hre;
                    }
                } else {
    
    
                    throw Exceptions.sneakyThrow(t);
                }
            }
        }
        return f;
    }

    //获取失败回退的方法名称,即我们自己配的降级方法
    @Override
    protected String getFallbackMethodName() {
    
    
        return "getFallback";
    }

    @Override
    protected boolean isFallbackUserDefined() {
    
    
        Boolean containsFromMap = commandContainsFallback.get(commandKey);
        if (containsFromMap != null) {
    
    
            return containsFromMap;
        } else {
    
    
            Boolean toInsertIntoMap;
            try {
    
    
                getClass().getDeclaredMethod("getFallback");
                toInsertIntoMap = true;
            } catch (NoSuchMethodException nsme) {
    
    
                toInsertIntoMap = false;
            }
            commandContainsFallback.put(commandKey, toInsertIntoMap);
            return toInsertIntoMap;
        }
    }

    @Override
    protected boolean commandIsScalar() {
    
    
        return true;
    }
}


第三部分:线程池资源调度和关闭

//熔断的切面bean对象和资源的释放
@Configuration(proxyBeanMethods = false)
public class HystrixCircuitBreakerConfiguration {
    
    

    //熔断器切面对象注入
    @Bean
    public HystrixCommandAspect hystrixCommandAspect() {
    
    
        return new HystrixCommandAspect();
    }


    //关闭的钩子处理
    @Bean
    public HystrixShutdownHook hystrixShutdownHook() {
    
    
        return new HystrixShutdownHook();
    }

    @Bean
    public HasFeatures hystrixFeature() {
    
    
        return HasFeatures
                .namedFeatures(new NamedFeature("Hystrix", HystrixCommandAspect.class));
    }

    //关闭
    private class HystrixShutdownHook implements DisposableBean {
    
    

        @Override
        public void destroy() throws Exception {
    
    
            //线程池的释放,关闭线程池
            Hystrix.reset();
        }

    }
}



//该线程池实现资源的隔离调度
public interface HystrixThreadPool {
    
    
    //获得线程池
    public ExecutorService getExecutor();

    //调度任务
    public Scheduler getScheduler();

    public Scheduler getScheduler(Func0<Boolean> shouldInterruptThread);

    //线程开始执行的标记
    public void markThreadExecution();

    //线程完成命令的标记
    public void markThreadCompletion();

    //命令被拒绝的标记
    public void markThreadRejection();

    //队列是否有可用空间
    public boolean isQueueSpaceAvailable();

    //内部类
    static class Factory {
    
    
        //保存资源的线程池  通过map结构来实现资源隔离
        final static ConcurrentHashMap<String, HystrixThreadPool> threadPools = new ConcurrentHashMap<String, HystrixThreadPool>();

        //获取某个服务的线程池
        static HystrixThreadPool getInstance(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties.Setter propertiesBuilder) {
    
    
            //某个服务的线程池对应的key
            String key = threadPoolKey.name();

            //根据key查找对应服务的线程池
            HystrixThreadPool previouslyCached = threadPools.get(key);
            if (previouslyCached != null) {
    
    
                return previouslyCached;
            }

            // 缓存没有说明此次进入创建该服务的线程池
            synchronized (HystrixThreadPool.class) {
    
    
                if (!threadPools.containsKey(key)) {
    
    
                    threadPools.put(key, new HystrixThreadPoolDefault(threadPoolKey, propertiesBuilder));
                }
            }
            return threadPools.get(key);
        }

        //关闭所有线程池
        static synchronized void shutdown() {
    
    
            //关闭指定资源(服务)的线程池
            for (HystrixThreadPool pool : threadPools.values()) {
    
    
                pool.getExecutor().shutdown();
            }
            //清理线程池
            threadPools.clear();
        }
    }

    //内部类 HystrixThreadPool线程池 的默认实现
    static class HystrixThreadPoolDefault implements HystrixThreadPool {
    
    
        private static final Logger logger = LoggerFactory.getLogger(HystrixThreadPoolDefault.class);
        //线程池容量大小的配置
        /*
        static int default_coreSize = 10;            // 核心线程池大小
        static int default_maximumSize = 10;         // 最大线程数
        static int default_keepAliveTimeMinutes = 1; // 现成晟敏周期1分钟
        static int default_maxQueueSize = -1;        // 队列大小
        //......
        *  */
        private final HystrixThreadPoolProperties properties;
        //阻塞队列,自动弹出
        private final BlockingQueue<Runnable> queue;
        //线程池
        private final ThreadPoolExecutor threadPool;
        //度量统计,即UI页面上的监控数据
        private final HystrixThreadPoolMetrics metrics;
        //队列大小
        private final int queueSize;

        //返回配置后的线程池,一个资源(服务)对应一个线程池
        @Override
        public ThreadPoolExecutor getExecutor() {
    
    
            touchConfig();
            return threadPool;
        }

        @Override
        public Scheduler getScheduler() {
    
    
            //调用超时,中断底层正在IO的线程
            return getScheduler(new Func0<Boolean>() {
    
    
                @Override
                public Boolean call() {
    
    
                    return true;
                }
            });
        }

        @Override
        public Scheduler getScheduler(Func0<Boolean> shouldInterruptThread) {
    
    
            touchConfig();
            return new HystrixContextScheduler(HystrixPlugins.getInstance().getConcurrencyStrategy(), this, shouldInterruptThread);
        }

        //默认属性  抓取配置   线程池初始化
        private void touchConfig() {
    
    
            final int dynamicCoreSize = properties.coreSize().get();
            final int configuredMaximumSize = properties.maximumSize().get();
            int dynamicMaximumSize = properties.actualMaximumSize();
            final boolean allowSizesToDiverge = properties.getAllowMaximumSizeToDivergeFromCoreSize().get();
            boolean maxTooLow = false;

            if (allowSizesToDiverge && configuredMaximumSize < dynamicCoreSize) {
    
    
                dynamicMaximumSize = dynamicCoreSize;
                maxTooLow = true;
            }

            if (threadPool.getCorePoolSize() != dynamicCoreSize || (allowSizesToDiverge && threadPool.getMaximumPoolSize() != dynamicMaximumSize)) {
    
    
                if (maxTooLow) {
    
    
                    logger.error("Hystrix ThreadPool configuration for : " + metrics.getThreadPoolKey().name() + " is trying to set coreSize = " +
                            dynamicCoreSize + " and maximumSize = " + configuredMaximumSize + ".  Maximum size will be set to " +
                            dynamicMaximumSize + ", the coreSize value, since it must be equal to or greater than the coreSize value");
                }
                threadPool.setCorePoolSize(dynamicCoreSize);
                threadPool.setMaximumPoolSize(dynamicMaximumSize);
            }

            threadPool.setKeepAliveTime(properties.keepAliveTimeMinutes().get(), TimeUnit.MINUTES);
        }
        //........
    }
}

猜你喜欢

转载自blog.csdn.net/GiantCrocodile/article/details/124898653
今日推荐