承接上文
从依赖入手分析
![](https://i-blog.csdnimg.cn/blog_migrate/26b0240d58704c94ad1eb0c49bb0a3e6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/49e0babff858378fc8ba550341aa72b4.png)
SentinelAutoConfiguration类中有SentinelResourceAspect bean定义
![](https://i-blog.csdnimg.cn/blog_migrate/cc4b756131cd74338e49c5165d43f9d6.png)
@ConditionalOnMissingBean 这个注解表示当没有这个bean存在的时候 就创建;AOP切面
切入点
![](https://i-blog.csdnimg.cn/blog_migrate/53a1f5ab23cc86b676479f7823771107.png)
环绕通知注解完成目标方法的调用
![](https://i-blog.csdnimg.cn/blog_migrate/0d143204b22c97e3cb547f53ac05e0e1.png)
SphU.entry 获取目标资源
在这之前没有创建Context 所以就会创建默认的Context
![](https://i-blog.csdnimg.cn/blog_migrate/ef8b251b22b38bb4d4f2acb9179060b9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d85e6c2f8f1107d2ad748b9a6a54cfd3.png)
count参数表示当前请求可以增加多少个计数
默认是1 即一个请求过来之后 访问数量增加1
注意第五个参数值是false
返回一个具有优先级的资源对象
![](https://i-blog.csdnimg.cn/blog_migrate/ac3467da28dfa781c3c66238bfd5a226.png)
优先级参数默认为false
获取Context
![](https://i-blog.csdnimg.cn/blog_migrate/b061fd9382a41147b0bbdce1b288e461.png)
![](https://i-blog.csdnimg.cn/blog_migrate/40b6e58dfb449aa22716355d70b49ce0.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b068a70269c64e2ad0fffafd377e29b6.png)
从ThreadLocal中获取即Context和当前线程是绑定的
一个请求会占用一个线程,一个线程会绑定一个context
![](https://i-blog.csdnimg.cn/blog_migrate/72a1feb2132d05162a7e5259e2647510.png)
![](https://i-blog.csdnimg.cn/blog_migrate/46dae8adce6293c3b4441300842a4d2a.png)
创建默认的context
![](https://i-blog.csdnimg.cn/blog_migrate/f8f58b5d47d9622c984c3df014842cda.png)
![](https://i-blog.csdnimg.cn/blog_migrate/77b4b263a2ddc04adad793e329155c8a.png)
确认一个contxt 需要2个属性 一个是资源名称一个是来源
![](https://i-blog.csdnimg.cn/blog_migrate/4b2fc3c8c4872cd527ef00fb715b1ff7.png)
新建node放入缓存map 该写法为了防止迭代稳定性问题
![](https://i-blog.csdnimg.cn/blog_migrate/e28404a6801f58a7ffd6eb3c522f5c7e.png)
对于共享集合的写操作 要采用这种方式 否则可能会读到脏数据
查找SlotChain
![](https://i-blog.csdnimg.cn/blog_migrate/007471c264ac762d6a45b8726a092819.png)
具体创建SlotChain的过程
![](https://i-blog.csdnimg.cn/blog_migrate/69588a7ab296f432970a40a46dbe48c4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/eef115ff4e737123508fe7d9de4e4dc9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d277d95b269257700bec8b3349c0aeb0.png)
怎么build一个chain
![](https://i-blog.csdnimg.cn/blog_migrate/46b8f318a130744e912232af054a323a.png)
又是通过SPI读取配置文件进行构建
![](https://i-blog.csdnimg.cn/blog_migrate/3547aeb26d4cfdfaab5a3cf7581080ff.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5a907187a7491cbabdf085529dbefca2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2367b36430e9c4b4ccdb0c8180cda5b3.png)
每个slot都会有一个order标签 越小加载的优先级更高
![](https://i-blog.csdnimg.cn/blog_migrate/501d0e6b37f474b3c3071c7385dcf77d.png)
ProcessorSlotChain是一个单向链表 默认包含一个节点
![](https://i-blog.csdnimg.cn/blog_migrate/ffd0b2b8b024f8aaff84cc469e64ab23.png)
first和ent这两个指针都指向了一个节点
chain.entry 对资源进行操作
该chain就是DefaultProcessorSlotChain 单向链表
转换操作对象即从first节点转换下一个节点
![](https://i-blog.csdnimg.cn/blog_migrate/812f01b4de3f11ef1ae917964e31276c.png)
下一个节点才是真正创建的 不是默认创建的
进入下一个节点
![](https://i-blog.csdnimg.cn/blog_migrate/d8c848bc6ffa8bd2d98c016616f5b338.png)
下一个节点是谁?
![](https://i-blog.csdnimg.cn/blog_migrate/37601cec08c406a236e81e2096fc5894.png)
第一个首先走的是NodeSelectorSlot
这个是干嘛的?创建节点调用树的
![](https://i-blog.csdnimg.cn/blog_migrate/cdd06407b7e8ccaec266ce7631deb730.png)
这个调用树中的EntranceNode在Context已经创建了 还差DefaultNode
![](https://i-blog.csdnimg.cn/blog_migrate/d2e7d93ec079c063d2aeec5892b3c6db.png)
先从缓存中获取DefaultNode
然后双重检查校验DCL 防止重复创建
创建DefaultNode并放入缓存中
将新建Node添加到调用树中
然后再出发下一个节点ClusterBuilderSlot
![](https://i-blog.csdnimg.cn/blog_migrate/4760fb781713027e9caee159312d05df.png)
![](https://i-blog.csdnimg.cn/blog_migrate/feefa123c7118eec88fcbb58a5b7f109.png)
然后再下个节点就是StaticSlot
![](https://i-blog.csdnimg.cn/blog_migrate/a7eb979e3f4a9a2cc85f75f47f6b4682.png)
![](https://i-blog.csdnimg.cn/blog_migrate/963e5c25e204ed9dd7d8932dc7dcb7de.png)
FlowSlot
![](https://i-blog.csdnimg.cn/blog_migrate/3f6f64ffee3ae97b3a7ce8373c4e3a2d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0526fa3b47d4394fa5517636b1b95a0f.png)
FlowRule
包含的属性:
resource 资源名称
limitapp 来源 默认default 所有来源应用
grade 阈值类型 0=线程数限流 1=QPS限流
count 阈值
strategy 流控模式 :直接、关联、链路
refResource 如果流控模式是关联,关联资源是什么
流控效果 0=快速失败,1=warm up(令牌桶算法),2=排队等待(漏斗算法),3=warm up+排队等待
warmUpPeriodSec 预热时长
maxQueueingTimeMs 排队等待超时时间
clusterMode 是否是集群模式
获取指定资源的所有流控规则
![](https://i-blog.csdnimg.cn/blog_migrate/3c654f26d3365689fc092f0de5556a9c.png)
检查规则是否可以通过
![](https://i-blog.csdnimg.cn/blog_migrate/c18335c76dbd49f79872891442944dcb.png)
单机流控
![](https://i-blog.csdnimg.cn/blog_migrate/e7ff392ad0277696d1b1bec5ac6a0e38.png)
根据不同的流控效果选择不同的校验类
![](https://i-blog.csdnimg.cn/blog_migrate/c959349d26a052909bf0a79b6ca33e59.png)
快速失败的流控效果中的通过性判断
![](https://i-blog.csdnimg.cn/blog_migrate/a5b3e924518d91f59fbacb6e2c7211a8.png)
获取当前时间窗已经统计的数据
![](https://i-blog.csdnimg.cn/blog_migrate/ca45140fec1f4c53c0b294f2fa283dd9.png)
计算QPS
![](https://i-blog.csdnimg.cn/blog_migrate/971e100d16d5991f4d040a8ecccb322b.png)
熔断降级DegradeSlot
![](https://i-blog.csdnimg.cn/blog_migrate/0d12d15049075e22d87882ac2a5a0cbf.png)
熔断逻辑
![](https://i-blog.csdnimg.cn/blog_migrate/0f40e151809c78f534ba336975488343.png)
CircuitBreaker
1.8版本将三种熔断策略(慢调用/异常比/异常数)
封装为2中策略 :
响应时间熔断器与异常熔断器
-
getRule
获取降级规则
-
tryPass
判断请求是否可以通过
返回true 表示通过 则不用降级
否则降级
-
onRequestComplete
回调方法,当请求通过并完成后会触发
-
currentState
获取当前熔断器的状态
State
OPEN: 打开状态,会拒绝所有
CLOSED:关闭状态,所有请求可以通过
HALF_OPEN:过渡状态,尝试性调用 如果请求不正常(响应很慢)则OPEN即请求拒绝;否则CLOSED 允许请求访问
![](https://i-blog.csdnimg.cn/blog_migrate/dee266a250b7ca00e68181c861cb2af9.png)
结语
下回分解滑动时间窗口原理及源码~