Sentinel源码
2021-08-18 10:07:03 0 举报
Sentinel
作者其他创作
大纲/内容
如果当前计算出的窗口还未初始化 创建一个窗口 时间长度是1000ms(分钟级) 并设置窗口的开始时间并CAS方式放入滑动窗口数组中 并返回
counters[event.ordinal()].add(n)
HeartbeatSenderInitFunc
exit
如果计算出的窗口开始时间 和从数组中取出的窗口的开始时间相等, 说明当前请求还在时间窗口内 则返回老的窗口
SPI机制加载
DefaultSlotChainBuilder.build()
时间窗口的请求数据是放在窗口内部LongAdder数组中不同的下标代表不同统计指标
fromHalfOpenToOpen(1.0d)
1.增加RT和调用完成数2.减少当前通过线程数
SpiLoader.of(InitFunc.class).loadInstanceListSorted()
rt maxAllowedRt断路器半开状态一般是尝试了一次请求,如果响应时间依然超过最大RT则打开断路器
selectNodeByRequesterAndStrategy
断路器关闭状态返回true
客户端和sentinel控制台交互源码
增加通过调用数
LongAdder正常,增加通过线程数
匀速排队
构建处理责任链
SpiLoader.of(ProcessorSlot.class).loadInstanceListSorted()
AuthoritySlot黑白名单控制
fireEntry
计算窗口下标
流控规则
slotChainBuilder.build()
SentinelAutoConfiguration自动配置类
SpringBoot项目启动时会加载jar包下的spring.factory文件配置的类
增加当前时间窗口的被限流数
@Bean拦截@SentinelResource注解的AOP类
canPassCheck
打开状态
InitExecutor.doInit()
updateNextRetryTimestamp()
RateLimiterController漏桶算法
调用异常数比例逻辑判断
获取该resource对应的所有的熔断规则 逐一规则比对
关闭状态
判断后续规则通过状态
熔断降级判断
1.如果当前时间算出的窗口开始时间 大于 数组中老的窗口开始时间,2.则重置老的窗口开始时间变为当前时间
加载sentinel-core.jar中META-INF下services目录下com.xx.ProcessorSlot文件的扩展类
统计指标健康信息等后面的节点处理完毕以后,它再进行统计数据
给冷系统一个预热的时间,避免冷系统被压垮。,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。使用到数学斜线斜率
transformToOpen(currentRatio)
根据资源设置的类型,选择流控策略
DefaultController
wrap.value().addPass(count)
ExceptionCircuitBreaker
BlockException
当前时间戳 / 1000ms(每个窗口的实时间长度) % 60(窗口个数)
DegradeSlot熔断降级验证
从当前时间窗口内取出统计指标,当前QPS大于阈值 则返回false 不通过
先处理责任链上后面的那些节点抛出了BlockException才做处理
Env.sph.entryWithType
FlowSlot
慢调用比例=慢调用次数*1.0d/总调用次数资源慢调用比例超过阈值,断路器打开
long windowStart = calculateWindowStart(timeMillis)
当前时间窗口
全局系统保护规则
int idx = calculateTimeIdx(timeMillis)
逐个调用每个solt的退出方法(exit)
lookProcessChain(resourceWrapper)
1.AbstractLinkedProcessorSlot first2.NodeSelectorSlot3.ClusterBuilderSlot4.LogSlot5.StatisticSlot6.SystemSlot7.AuthoritySlot8.FlowSlot9.DegradeSlot
currentState.get() == State.HALF_OPEN处于半开状态
Throwable
CommandCenterInitFunc
如果熔断器状态为开启,并且已经超过熔断时长以及开启状态成功转换为半开启(探测)状态返回true,即允许请求通过
根据下标获取窗口
SphU.entry(resourceName)
resetStat()
半开状态
增加当前时间窗口异常数指标
统计资源的总调用次数和慢调用次数
预约/冷启动
根据配置,更新断路器的熔断时长就是控制台配置的降级时长
如果请求响应时间超过最大的RT时间
效验不通过抛BlockException
counter.slowCount.add(1)
判断QPS或线程数是否大于阈值
判断当前资源的断路器状态
passLocalCheck
总调用次数+1
Env.sph
init
circuitBreaker.onRequestComplete(context)
SPI机制加载InitFunc接口加载sentinel-transport-common.jar.jar中META-INF下services目录
ruleProvider.apply(resource.getName())
WindowWrap<MetricBucket> wrap = data.currentWindow()
构建资源solt效验链
node.increaseThreadNum()
如果这次尝试调用的响应时间小于最大RT则关闭断路器
performChecking
总调用次数< 5(默认值)直接return不修改断路器状态
node.addPassRequest(count)
获取资源相关的效验规则
StatisticSlot
if (totalCount minRequestAmount)
单机流控验证
LogSlot
方法执行结束 退出
处理断路器状态
重置慢调用和统计次数为0
从数组中获取当前时间所在的窗口
fromHalfOpenToClose()
触发扩展类的初始化
启动一个定时任务,首次初始化延时5s执行发送一次心跳,后面就每隔10秒向控制台发送心跳包
快速失败
NodeSelectorSlot
DegradeSlot..exit
SystemSlot
1.异常数+12. 总调用次数+1
如果当前断路器是open状态直接return结束
handleStateChangeWhenThresholdExceeded(rt)
counter.totalCount.add(1)
申请一个资源,如果成功则表示未限流负责抛出BlockException异常
SlotChainProvider.newSlotChain()
WindowWrap<T> old = array.get(idx)
1.通过使用 latestPassedTime 属性来记录最后一次通过的时间,然后根据设置的QPS判断当前请求是否可以通过,可以通过则latestPassedTime2.比如设置 QPS 为 10,那么每 100 毫秒允许通过一个,如果此时距离上一次请求才过了50ms,则需要等待50ms才让通过,如果同时有另一个请求,则需要等待150ms
StatisticSlot.exit指标统计
慢调用比例逻辑判断
cb.tryPass(context)
ResponseTimeCircuitBreaker
收集资源的路径
拿到当前窗口的MetricBucket增加窗口通过数
计算该窗口开始时间 当前时间戳 - 当前时间戳 % 1000ms(每个窗口的时间长度)timeMillis - timeMillis % windowLengthInMs
WarmUpController令牌桶算法
ClusterBuilderSlot
逐个效验
同时增加分钟级别和秒级别的窗口的统计指标
SentinelResourceAspect
0 条评论
回复 删除
下一页