Sentinel系列文章

Sentinel熔断限流器工作原理

Sentinel云原生K8S部署实战

Sentinel核心源码解析

时间窗限流算法

如图 
10-20这个时间窗内请求数量是60小于阈值100,这60个请求均可以通过
30-40这个时间窗请求数量是120大于阈值100,其中有20个请求不能通过

弊端

10t到16t 10个请求
16t-20t 50个请求
20t-26t 60个请求
26t到30t 20个请求

16t到26t 有了110个请求 超过了阈值 
但这种固定时间窗口算法就不会做限制
不能做到任意时间段内做限流

滑动时间窗口

从黄线位置往前推一个时间窗口
看该时间窗窗口内请求数量是否大于阈值
如果大于阈值 该点的请求被拦截
小于阈值 则允许访问
这种情况有8个请求不能通过

滑动时间窗口实现了在任意时间段内请求数量都不能超过阈值

但它也带来了新的问题 "重复统计 浪费系统资源"
分析点1和分析点2对应的2个时间窗有重叠的统计的部分

滑动时间窗口算法改进

如图每个时间窗100t、分成4段 每段25t 每一段对应一个统计数组元素
比如100-125这一段对应 a0 这个数组元素 记录了100-125这单位时间窗内的请求数量

上图棕色线在130的位置 属于125t-150t 这个单位时间窗口 对应数组a1元素
如果请求属于125t-150t这一窗口 统计的请求量都会加到该窗口对应的a1中

判断180t这点的请求是否可以通过

计算175t-180t之间的请求量 该时间窗对应a3
则获取a0的统计值+a1的统计值+a2的统计值+ (175t到180t之间的请求量)
看是否超过了阈值100
如果超过则不能通过
如果没有超过则可以通过

滑动时间窗口源码解析

  • 对数据的统计
  • 对统计数据的使用

分析这个方法

ArrayMetric

LeapArray

WindowWrap样本窗口实例 范型T为MetricBucket

windowLengthInMs 样本窗口长度
windowStart 样本窗口的起始时间戳
value 当前样本窗口的统计数据 其类型为MetricBucket

MetricBucket

MetricEvent数据统计的维度

统计这个时间窗口内 通过请求量、拦截请求量、异常请求量、成功请求量等6个维度的数据 放在LongAddr数组中

获取当前时间点所在的样本窗口

计算当前时间所在的样本窗口id

获取当前时间窗的开始时间

1、首先计算27t位于哪个时间窗:27/10=2

下标是0 落在下标为2的位置

2、计算27t这点的请求统计量累计在哪个LeapArray元素中

2%4=2 即a2的位置

3、获取27t所在窗口的开始时间

27t-27%10=20t

替换掉老的时间窗口

对象本身没变

将当前窗口的请求数据添加到当前样本窗口的统计数据中

通过维度数据

对统计数据如何使用

流控快速失败

以前的加上现在的

获取之前统计好的数据

遍历数据将pass维度的数据取出来 求和
将当前遍历的样本窗口统计数据记录到result中

过时判断

当前时间-窗口起始时间 比时间窗还大 那就是过时了
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐