Sentinel核心源码解析

336 阅读3分钟

承接上文

Sentinel熔断限流器工作原理

Sentinel云原生K8S部署实战

从依赖入手分析

SentinelAutoConfiguration类中有SentinelResourceAspect bean定义

@ConditionalOnMissingBean 这个注解表示当没有这个bean存在的时候 就创建;AOP切面

切入点

环绕通知注解完成目标方法的调用

SphU.entry 获取目标资源
在这之前没有创建Context 所以就会创建默认的Context

count参数表示当前请求可以增加多少个计数
默认是1 即一个请求过来之后 访问数量增加1
注意第五个参数值是false

返回一个具有优先级的资源对象

优先级参数默认为false

获取Context

从ThreadLocal中获取即Context和当前线程是绑定的
一个请求会占用一个线程,一个线程会绑定一个context

创建默认的context

确认一个contxt 需要2个属性 一个是资源名称一个是来源

新建node放入缓存map 该写法为了防止迭代稳定性问题

对于共享集合的写操作 要采用这种方式 否则可能会读到脏数据

查找SlotChain

具体创建SlotChain的过程

怎么build一个chain

又是通过SPI读取配置文件进行构建

每个slot都会有一个order标签 越小加载的优先级更高

ProcessorSlotChain是一个单向链表 默认包含一个节点

first和ent这两个指针都指向了一个节点

chain.entry 对资源进行操作

该chain就是DefaultProcessorSlotChain 单向链表

转换操作对象即从first节点转换下一个节点

下一个节点才是真正创建的 不是默认创建的

进入下一个节点

下一个节点是谁?

第一个首先走的是NodeSelectorSlot
这个是干嘛的?创建节点调用树的

这个调用树中的EntranceNode在Context已经创建了 还差DefaultNode

先从缓存中获取DefaultNode
然后双重检查校验DCL 防止重复创建

创建DefaultNode并放入缓存中
将新建Node添加到调用树中

然后再出发下一个节点ClusterBuilderSlot

然后再下个节点就是StaticSlot

FlowSlot

FlowRule

包含的属性:
resource 资源名称
limitapp 来源 默认default 所有来源应用
grade 阈值类型 0=线程数限流 1=QPS限流
count 阈值
strategy 流控模式 :直接、关联、链路
refResource 如果流控模式是关联,关联资源是什么
流控效果 0=快速失败,1=warm up(令牌桶算法),2=排队等待(漏斗算法),3=warm up+排队等待
warmUpPeriodSec 预热时长
maxQueueingTimeMs 排队等待超时时间
clusterMode 是否是集群模式

获取指定资源的所有流控规则

检查规则是否可以通过

单机流控

根据不同的流控效果选择不同的校验类

快速失败的流控效果中的通过性判断

获取当前时间窗已经统计的数据

计算QPS

熔断降级DegradeSlot

熔断逻辑

CircuitBreaker

 1.8版本将三种熔断策略(慢调用/异常比/异常数)
 封装为2中策略 :
 响应时间熔断器与异常熔断器
  • getRule
获取降级规则
  • tryPass
判断请求是否可以通过
返回true 表示通过 则不用降级
否则降级
  • onRequestComplete
回调方法,当请求通过并完成后会触发
  • currentState
获取当前熔断器的状态

State

OPEN: 打开状态,会拒绝所有
CLOSED:关闭状态,所有请求可以通过
HALF_OPEN:过渡状态,尝试性调用 如果请求不正常(响应很慢)则OPEN即请求拒绝;否则CLOSED 允许请求访问

结语

下回分解滑动时间窗口原理及源码~