目录
1. 概述
之前分析过Sentinel是基于责任链的模式,其逻辑处理部分是一个有一个的Slot
这里大概的介绍下每种Slot的功能职责:
-
NodeSelectorSlot
负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降级; -
ClusterBuilderSlot
则用于存储资源的统计信息以及调用者信息,例如该资源的 RT, QPS, thread count 等等,这些信息将用作为多维度限流,降级的依据; -
StatisticsSlot
则用于记录,统计不同维度的 runtime 信息; -
SystemSlot
则通过系统的状态,例如 load1 等,来控制总的入口流量; -
AuthoritySlot
则根据黑白名单,来做黑白名单控制; -
FlowSlot
则用于根据预设的限流规则,以及前面 slot 统计的状态,来进行限流; -
DegradeSlot
则通过统计信息,以及预设的规则,来做熔断降级;
每个Slot执行完业务逻辑处理后,会调用fireEntry()方法,该方法将会触发下一个节点的entry方法,下一个节点又会调用他的fireEntry,以此类推直到最后一个Slot,由此就形成了sentinel的责任链。
2. 一些需要知道的前提
2.1. Resource
资源,是Sentinel世界中的抽象,任何东西都能被定义成资源,自己提供的服务,调用的服务,甚至一段代码,有了资源才能在资源上定义规则,去进行限流降级之类的操作
在Sentinel中提供了两个默认是Resource分别是StringResourceWrapper和MethodResourceWrapper
2.2. Context
Context是上下文的意思,一个线程对应一个Context
其中有三个属性
- name:名字
- entranceNode:调用链入口
- curEntry:当前entry
- origin:调用者来源
- async:异步
2.3. Entry
每次调用 SphU.entry()
都会生成一个Entry入口,该入口中会保存了以下数据:入口的创建时间,当前入口所关联的节点(Node),当前入口所关联的调用源对应的节点。Entry是一个抽象类,他只有一个实现类,在CtSph中的一个静态类:CtEntry
其中有这些属性
- createtime
- curNode
- originNode
- error
- resourceWrapper
- parent
- child
- chain
- context
红色的是抽象类Entry的,黑色的是CtEntry中的
一个Entry相当于一个token只有正常生成了一个entry才能算pass,不然报异常BlockException肯定是限流了
2.4. Node
节点是用来保存某个资源的各种实时统计信息的,他是一个接口,通过访问节点,就可以获取到对应资源的实时状态,以此为依据进行限流和降级操作。
有几种节点类型
- StatisticNode:统计节点
- DefaultNode:默认节点,NodeSelectorSlot中创建的就是这个节点
- ClusterNode:集群节点
- EntranceNode:该节点表示一棵调用链树的入口节点,通过他可以获取调用链树中所有的子节点
3. 深入分析
3.1. demo启动
Entry entry = null;
try {
entry = SphU.entry("abc");
entry = SphU.entry("abc");
} catch (BlockException e1) {
} finally {
if (entry != null) {
entry.exit();
}
}
CtSph.entryWithPriority
private Entry entryWithPriority(ResourceWrapper resourceWrapper, int count, boolean prioritized, Object... args)
throws BlockException {
//先从ThreadLocal获取,第一次肯定是null
Context context = ContextUtil.get