Sentinel中有很多类型的Node,例如DefaultNode、StatisticNode、ClusterNode、还有个EntranceNode总共四种类型的Node,第一次看的时候非常懵逼,Node是啥?四个Node有什么不同?
上篇文章中,我们看到StatisticSlot中使用了Node去统计了请求信息,那么Node应该就是做请求统计用的,看下Node接口里定义
public interface Node {
long totalRequest();
long totalSuccess();
long blockRequest();
long totalException();
long passQps();
long blockQps();
long totalQps();
long successQps();
long maxSuccessQps();
long exceptionQps();
long avgRt();
long minRt();
int curThreadNum();
long previousBlockQps();
long previousPassQps();
Map<Long, MetricNode> metrics();
void addPassRequest(int count);
void addRtAndSuccess(long rt, int success);
void increaseBlockQps(int count);
void increaseExceptionQps(int count);
void increaseThreadNum();
void decreaseThreadNum();
void reset();
void debug();
}
方法比较多,但是方法名字很清晰,那么可以得出结论:
- 内部实现可以不说,但是对外部来说Node是做为一个请求数据统计和获取的载体
另外再看下四个Node的关系:
那么这四个Node中,哪个去实现了Node接口的方法呢? 通过代码看到是StatisticNode实现了Node接口的所有方法,也就是说,另外三个Node有两种可能的作用:
- DefaultNode、ClusterNode、EntranceNode继承于StatisticNode,基于其提供的数据统计和获取方法,实现自身一些特殊逻辑
- StatisticNode提供了默认的方法,DefaultNode、ClusterNode、DntranceNode有自身的计算逻辑,需要重写这些方法
接下来通过具体代码分析,来看下到底是哪种情况。
EntranceNode
首先在上一篇文章中,我们从入口开始分析了整个调用链路流程,最先遇到和Node相关的代码的时候,是在ContextUtil#trueEnter
中
//#com.alibaba.csp.sentinel.Constants
public final static DefaultNode ROOT = new EntranceNode(new StringResourceWrapper(ROOT_ID, EntryType.IN),
Env.nodeBuilder.buildClusterNode());
//ContextUtil#trueEnter
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 (contextNameNodeMap.size() > Constants.MAX_CONTEXT_NAME_SIZE) {
//....
} else {
node = new EntranceNode(new StringResourceWrapper(name, EntryType.IN), null);
// Add entrance node.
Constants.ROOT.addChild(node);
Map<String, DefaultNode> newMap = new HashMap<String, DefaultNode>(
contextNameNodeMap.size() + 1);
newMap.putAll(contextNameNodeMap);
newMap