hystrix源碼之hystrix請求變量
HystrixRequestContext
請求的上線文實現,內部定義了一個靜態變量ThreadLocal,每個線程可以獲取自己的HystrixRequestContext對象。一個請求往往由一個tomcat線程處理,所以在該tomcat線程中,HystrixRequestContext對象可以共享。
private static ThreadLocal<HystrixRequestContext> requestVariables = new ThreadLocal<HystrixRequestContext>();
HystrixRequestContext內部是一個ConcurrentHashMap存儲請求變量。
ConcurrentHashMap<HystrixRequestVariableDefault<?>, HystrixRequestVariableDefault.LazyInitializer<?>> state = new ConcurrentHashMap<HystrixRequestVariableDefault<?>, HystrixRequestVariableDefault.LazyInitializer<?>>();
HystrixRequestVariableLifecycle->HystrixRequestVariable->HystrixRequestVariableDefault->HystrixLifecycleForwardingRequestVariable
HystrixRequestVariableLifecycle和HystrixRequestVariable定義了一個請求變量,這個請求變量對象的生命周期為在一個請求內。
HystrixRequestVariableDefault為默認實現類。內部他把變量值存儲在HystrixRequestContext對象中。key為當前HystrixRequestVariableDefault對象,value為變量真正的值。
public T get() { if (HystrixRequestContext.getContextForCurrentThread() == null) { throw new IllegalStateException(HystrixRequestContext.class.getSimpleName() + ".initializeContext() must be called at the beginning of each request before RequestVariable functionality can be used."); } ConcurrentHashMap<HystrixRequestVariableDefault<?>, LazyInitializer<?>> variableMap = HystrixRequestContext.getContextForCurrentThread().state; // short-circuit the synchronized path below if we already have the value in the ConcurrentHashMap LazyInitializer<?> v = variableMap.get(this); if (v != null) { return (T) v.get(); } ....
HystrixLifecycleForwardingRequestVariable只是一個封裝對象,內部封裝了一個HystrixRequestVariableLifecycle對象。
private final HystrixRequestVariableLifecycle<T> lifecycle;
HystrixRequestVariableHolder
定義了一個靜態變量,存儲所有的HystrixRequestVariable對象,全局共享。
private static ConcurrentHashMap<RVCacheKey, HystrixRequestVariable<?>> requestVariableInstance = new ConcurrentHashMap<RVCacheKey, HystrixRequestVariable<?>>();
RVCacheKey由兩部分組成:當前HystrixRequestVariableHolder對象,指定HystrixConcurrencyStrategy對象。
public T get(HystrixConcurrencyStrategy concurrencyStrategy) { RVCacheKey key = new RVCacheKey(this, concurrencyStrategy); ...
如果沒有已經存在的HystrixRequestVariable對象,通過HystrixConcurrencyStrategy新建一個。
... if (rvInstance == null) { requestVariableInstance.putIfAbsent(key, concurrencyStrategy.getRequestVariable(lifeCycleMethods)); } ...
hystrix源碼之hystrix請求變量