归档
类结构
com.alibaba.csp.sentinel.context.Context
public class Context {
private final String name; // 名称
private DefaultNode entranceNode; // 当前调用树的入口节点
private Entry curEntry; // 当前处理入口(条目)
private String origin = ""; // 此上下文的来源(通常指示不同的调用者,例如服务使用者名称或来源IP)
private final boolean async;
}
创建
调用源参考:入口控制-进入资源 sign_m_002
com.alibaba.csp.sentinel.CtSph.InternalContextUtil
// CtSph 的内部类
private final static class InternalContextUtil extends ContextUtil {
// sign_m_010 创建上下文
static Context internalEnter(String name) {
return trueEnter(name, ""); // sign_m_020
}
static Context internalEnter(String name, String origin) {
return trueEnter(name, origin);
}
}
com.alibaba.csp.sentinel.context.ContextUtil
/** 上下文工具类 */
public class ContextUtil {
private static ThreadLocal<Context> contextHolder = new ThreadLocal<>();
private static volatile Map<String, DefaultNode> contextNameNodeMap = new HashMap<>();
private static final Context NULL_CONTEXT = new NullContext();
// sign_m_020 创建上下文
// 参数 name => "sentinel_default_context"
protected static Context trueEnter(String name, String origin) {
Context context = contextHolder.get();
if (context == null) {
Map<String, DefaultNode> localCacheNameMap = contextNameNodeMap;
DefaultNode node = localCacheNameMap.get(name);
if (node == null) {
if (localCacheNameMap.size() > Constants.MAX_CONTEXT_NAME_SIZE) { // 最大 2000
setNullContext();
return NULL_CONTEXT; // 超过限制返回空上下文
} else {
LOCK.lock(); // 加锁 (双重检测锁)
try {
node = contextNameNodeMap.get(name);
if (node == null) {
if (contextNameNodeMap.size() > Constants.MAX_CONTEXT_NAME_SIZE) {
setNullContext();
return NULL_CONTEXT; // 加锁再检测一次
} else {
node = new EntranceNode(new StringResourceWrapper(name, EntryType.IN), null); // 创建入口节点
Constants.ROOT.addChild(node); // 添加到根节点(的子节点集中)
Map<String, DefaultNode> newMap = new HashMap<>(contextNameNodeMap.size() + 1);
newMap.putAll(contextNameNodeMap);
newMap.put(name, node);
contextNameNodeMap = newMap; // COW 更换
}
}
} finally {
LOCK.unlock();
}
}
}
context = new Context(node, name); // 创建上下文
context.setOrigin(origin);
contextHolder.set(context); // 设置到线程变量
}
return context;
}
}