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