【GHS】Sentinel滑动窗口算法

编程开发   © 文章版权由 admin 解释,禁止匿名转载

#楼主# 2020-12-30


在前面搞清楚了Sentinel的使用后,大致理了一下Sentinel的责任链,搞清楚了这个,基本就已经梳理清楚sentinel-core模块的大部分内容,顺着这条链路可以继续梳理很多东西。

关于滑动窗口的原理,Sentinel为什么要使用滑动窗口,Sentinel是怎样使用的滑动,直接使用下面这两张图。一图胜千言,一张好的图足以说明问题,在这里我引用两张图。

Metric是一个度量单位接口,其具体实现下面需要提一下,在这里先不展开,只需要知道它存储的是一些执行数据,如成功数、异常数等。而在上面的StatisticNode.addPassRequest方法中就是分别调用两个维度的统计单位增加请求通过数量。从rollingCounterInSecond.addPass(count)这一句进入,对应的方法在ArrayMetric类中,这一个就是Metric的唯一实现。ArrayMetric.addPass这个方法代码如下:

@Override
public void addPass(int count) {
// 获取当前时间对应的窗口,返回的是当前窗口的一个包装类
WindowWrap wrap = data.currentWindow();
wrap.value().addPass(count);
}
可以看出这里就已经是滑动窗口算法的入口了。通过滑动窗口算法,使用当前时间获取一个合适的窗口,然后在这个窗口中增加通过的请求数。进入到代码里面,最终落实到了LeapArray的currentWindow方法中了。就LeapArray这个类名来说,非常有我在开篇第二张图的那味道了。

在看LeapArray.currentWindow这个方法之前,先来看一个短小简单但是足够核心的一个方法LeapArray.calculateTimeIdx,整个方法只有两行代码,如下:

private int calculateTimeIdx(long timeMillis) {
// 将传入的当前时间按照窗口时长进行分段,拿到当前时间对应的分段ID
long timeId = timeMillis / windowLengthInMs;
// 将当前时间的分段段ID对应到窗口数组的下标ID上
return (int)(timeId % array.length());
}
上面的array定义如下:

protected final AtomicReferenceArray> array;
其赋值在构造方法中,如下语句:

this.array = new AtomicReferenceArray<>(sampleCount);
通过上面这个方法,我们就能够得到当前时间对应的窗口在窗口数组中的位置了,接下来我们要做的事情就是根据这个位置取出对应的窗口返回去给对应的统计逻辑使用。

成为第一个回答人

评论

登录后才可发表内容
  • 主题

    10

  • 帖子

    48

  • 关注者

    0

Copyright © 2019 凯特网.   Powered by HYBBS 2.3.4  

Runtime:0.5593s Mem:2048Kb