Hystrix源码剖析

hystrix里面有很多有意思的地方,比如缓存、回退方法、滑动窗口...

本人目前理解不够透彻,暂打印回退方法栈来展示整个回退方法的流程,其他章节后续会补充进来。

代码基于注解方式,需引入包com.netflix.hystrix.hystrix-javanica

入口

注解依赖aspectj,com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect切面处理@HystrixCommand的方法注解,方法案例:

    /**
     * 故意抛出dubbo的超时异常
     * @param messageReq
     * @return
     */
    // HystrixCommandAspect
    // https://github.com/Netflix/Hystrix/wiki/Configuration
    @HystrixCommand(
            // HystrixCommandGroupKey
            groupKey = "MessageProxy",
            // HystrixCommandKey
            commandKey = "sendTimeout",
            commandProperties = {
                    //HystrixCommandProperties
                    @HystrixProperty(name = "execution.timeout.enabled", value = "false"),    //执行超时时间|default:1000
//                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000"),    //执行超时时间|default:1000|RPC本身支持超时选项则才优先RPC方式
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"), //触发断路最低请求数|default:20
                    @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),    //断路器恢复时间|default:5000
                    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),   //|触发短路错误率,单位%|default:50
                    @HystrixProperty(name = "fallback.isolation.semaphore.maxConcurrentRequests", value = "100"),   // 设置调用线程产生的HystrixCommand.getFallback()方法的允许最大请求数目。|default: 10
            },
            threadPoolProperties = {
                    //HystrixThreadPoolProperties
                    @HystrixProperty(name = "coreSize", value = "15"),  //线程池核心数|default:10 超过队列fallback
                    @HystrixProperty(name = "maxQueueSize", value = "-1"),  //队列长度|default:-1(SynchronousQueue)
                    @HystrixProperty(name = "keepAliveTimeMinutes", value = "1"),   // 设置存活时间,单位分钟| 默认值:1|如果coreSize小于maximumSize,那么该属性控制一个线程从实用完成到被释放的时间。
//                    @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"),   //队满拒绝服务阈值|default:5|此值生效优先于队满, maxQueueSize设置为-1,该属性不可用。
                    // Metrics统计属性
                    //@HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"),   // 设置滑动统计的桶数量。默认10。metrics.rollingStats.timeInMilliseconds必须能被这个值整除。
                    //@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1440")  //窗口维持时间|default:10000
            },
            // HystrixThreadPoolKey|threadPoolKey =
            fallbackMethod = "fallback")
    public BaseResp sendTimeout(MessageReq messageReq){
        return iMessageFacade.sendTimeout(messageReq, 5000L);
    }

上下文数据装载器

通过阅读HystrixCommandAspect执行逻辑,com.netflix.hystrix.contrib.javanica.command.MetaHolder装载了切面的上下文元数据

Fallback

在装载上下文元数据,创建CommandAction组装执行器

创建回退执行器com.netflix.hystrix.contrib.javanica.command::createFallbackAction

最后组装成命令执行器集com.netflix.hystrix.contrib.javanica.command.CommandActions

执行Command逻辑使用rxjava,串联事件链(缓存、熔断、),这里不做详述

关键逻辑定义了观察者异常,错误传播执行回退方法com.netflix.hystrix.AbstractCommand::executeCommandAndObserve.handleFallback

通过回退来处理故障com.netflix.hystrix.AbstractCommand::handleFailureViaFallback

获取回退处理方法或直接抛出异常com.netflix.hystrix.AbstractCommand::getFallbackOrThrowException

获取回退方法观察者com.netflix.hystrix.HystrixCommand::getFallbackObservable

最终执行的函数com.netflix.hystrix.GenericCommand::getFallback

这个回退方法的栈非常长,其他细节的暂时对源码剖析告一段落...

代码面前,了无秘密。

Last updated