Sentinel面试
# Sentinel面试
# 1.Sentinel的限流与Gateway的限流有什么差别
固定窗口计数器:将时间按照等时间间隔划分为多个窗口,在每个窗口的时间段每有一次请求就将该窗口的计数器加1,超过窗口限流阈值的请求都会被丢弃。
滑动窗口计数器:窗口再进行划分区间,越细越准确。
令牌桶:以固定的速率生成令牌,请求进入后只有拿到令牌后才能被处理。否则请求等待或者丢弃。(Gateway采用基于redis的令牌桶算法,Sentinel的热点参数限流)
漏桶算法:输出请求的流量曲线平滑。(Sentinel的排队等待限流)
# 2.核心源码
核心骨架是ProcessorSlotChain类,责任链slot分为两大类:
- 统计数据构建
- DefaultNode:代表链路树的一个资源,当一个资源出现在不同链路时,会创建不同的DefaultNode节点
- clusterNode:代表资源,只能有一个ClusterNode。
- StatisticSlot:统计
- 规则判断部分
添加@SentinelResource标记资源:对被标记的方法做环绕增强,基于AOP思想。创建资源Entry—>执行受保护的方法pjp.proceed(),也就是标注的资源代码—>catch异常,关闭entry。
# 3.热点参数限流
controller方法不能做热点参数限流,因为它是基于拦截器添加的资源,没有传入方法形参args。而基于@SentinelResource标注的资源在进行切面编程时,添加了args,因此可以实现热点参数限流。
计算桶内剩余的令牌数量是否可以满足当前需要的令牌数量:
- 生成的令牌数量=(经过的时长/每个统计窗口周期时长)*每个窗口生成的令牌数量
- 取max(生成的令牌数量+目前剩余令牌数量,桶限制的最大令牌数量)作为当前可使用令牌数量
- 更新剩余令牌数量=当前可使用令牌数量-请求的令牌数量
# 4.滑动时间窗口模式
采用一个环形数组来构建窗口
窗口号下标=(当前时间/每个窗口的时间间隔)%窗口数组大小
计算当前窗口的开始时间=当前时间-当前时间%每个窗口的时间间隔
根据计算的角标取出窗口old,然后返回作为当前窗口。可能会有如下三种情况
- old==null,说明当前请求是第一个到达old窗口。则设置old窗口的信息(windowstart起始时间...)
- windowstart==old.windowstart,计算得到所在窗口的起始时间和old当前窗口起始时间一致,说明有新的请求到达窗口
- windowstart>old.windowstart,请求起始时间已经饶了一圈,因此需要重置old窗口起始时间
获得当前窗口后,遍历所有数组窗口,根据当前时间-窗口起始时间>1s来找到符合算法的窗口,并计算QPS。
编辑 (opens new window)
上次更新: 2023/12/15, 15:49:57