通过源码理解Hystrix缓存的工作原理

AbstractCommand关键源码
protected final HystrixRequestCache requestCache;

//默认返回null
protected String getCacheKey(){
    return null;
}

protected boolean isRequestCachingEnabled(){
    //必须重写getCacheKey方法,让它返回一个非null的值,否则不会开启
    //请求命令缓存开启属性也需要设置为true才能开启(默认为true)
    return properties.requestCacheEnalbed().get && getCacheKey()!=null;
}

public Observable<R> toObservable() {
    final AbstractCommand<R> _cmd = this;
 ......
            final boolean requestCacheEnabled = isRequestCachingEnabled();
            final String cacheKey = getCacheKey();
            /*首先尝试从缓存中获取结果 */
            /*
            Hystrix命令再执行前根据isRequestCachingEnabled方法判断当前是否启用了请求缓存。如果启用了
            并且重写了getCacheKey方法,并返回了一个非null的缓存Key值,那么就使用getCacheKey返回的key
            去调用requestCache中的get方法来获取缓存的HystrixCacheObservable对象
            */
            if (requestCacheEnabled) {
                HystrixCommandResponseFromCache<R> fromCache = (HystrixCommandResponseFromCache<R>) requestCache.get(cacheKey);
                if (fromCache != null) {
                    isResponseFromCache = true;
                    return handleRequestCacheHitAndEmitValues(fromCache, _cmd);
                }
            }
            Observable<R> hystrixObservable =
                    Observable.defer(applyHystrixSemantics) //未使用缓存,则继续调用applyHystrixSemantics
                            .map(wrapWithAllOnNextHooks);
            Observable<R> afterCache;
            // 加入缓存
            if (requestCacheEnabled && cacheKey != null) {
                // wrap it for caching
                /*
                请求缓存对象HystrixRequestCache维护了一个线程安全的Map来保存请求缓存的响应,调用putIfAbsent,将包装
                的请求缓存放入缓存对象后,对其返回结果进行判断,如果不为null,说明当前缓存Key的请求命令缓存命中
                直接对toCache执行取消订阅操作(不再发起真实请求),同时调用 handleRequestCacheHitAndEmitValues
                来执行缓存命令的结果获取。如果fromCache为空,说明缓存没命中,则将当前结果toCache缓存起来,并将其转换
                成Observable返回给调用者使用。
                */
                HystrixCachedObservable<R> toCache = HystrixCachedObservable.from(hystrixObservable, _cmd);
                HystrixCommandResponseFromCache<R> fromCache = (HystrixCommandResponseFromCache<R>) requestCache.putIfAbsent(cacheKey, toCache);
                if (fromCache != null) {
                    // another thread beat us so we'll use the cached value instead
                    toCache.unsubscribe();
                    isResponseFromCache = true;
                    return handleRequestCacheHitAndEmitValues(fromCache, _cmd);
                } else {
                    // we just created an ObservableCommand so we cast and return it
                    afterCache = toCache.toObservable();
                }
            } else {
                afterCache = hystrixObservable;
            }
            return afterCache
                    .doOnTerminate(terminateCommandCleanup)     // perform cleanup once (either on normal terminal state (this line), or unsubscribe (next line))
                    .doOnUnsubscribe(unsubscribeCommandCleanup) // perform cleanup once
                    .doOnCompleted(fireOnCompletedHook);
        }
    });
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值