之前说过Sentinel内部统计使用Node来进行处理,而Node底层是使用滑动窗口实现的,这篇文章主要分析一下滑动窗口的实现。
以StatisticNode#addPassRequest
方法为入口,先看看内部实现:
private transient volatile Metric rollingCounterInSecond = new ArrayMetric(SampleCountProperty.SAMPLE_COUNT,
IntervalProperty.INTERVAL);
private transient Metric rollingCounterInMinute = new ArrayMetric(60, 60 * 1000);
@Override
public void addPassRequest(int count) {
rollingCounterInSecond.addPass(count);
rollingCounterInMinute.addPass(count);
}
addPassRequest
方法内部调用了rollingCounterInSecond.addPass
和rollingCounterInMinute.addPass
,看了下两个变量的声明,可以看到类型都是ArrayMetric
,只不过参数不一样,而从变量名来看,一个是统计一分钟的数据,一个是统计一秒钟的数据
那么看看ArrayMetric是什么东西,构造方法和成员变量如下
private final MetricsLeapArray data;
public ArrayMetric(int sampleCount, int intervalInMs) {
this.data = new MetricsLeapArray(sampleCount, intervalInMs);
}
内部只有一个MetricsLeapArray
类型,似乎又将统计的任务委托给了MetricsLeapArray
,抽两个方法看看其实现:
public void addPass(int count) {
// 获取当前窗口
WindowWrap<MetricBucket> wrap = data.currentWindow();
// 将数据统计在当前窗口中
wrap.value().addPass(count);
}
public long pass() {
data.currentWindow();
long pass = 0;
// 获取所有窗口
List<MetricBucket> list = data.values();
// 所有窗口的值累加返回
for (MetricBucket window : list) {
pass += window.pass();
}
return pass;
}
的确是核心实现是在MetricsLeapArray
中,这里只做一层转发、汇总
接着继续看下MetricsLeapArray
实现
public class MetricsLeapArray extends LeapArray<MetricBucket> {
public MetricsLeapArray(int sampleCount, int intervalInMs) {
super(sampleCount, intervalInMs);
}
@Override
public MetricBucket newEmptyBucket() {
return new MetricBucket();
}
@Override
protected WindowWrap<MetricBucket> resetWindowTo(WindowWrap<MetricBucket> w, long startTime) {
// Update the start time and reset value.
w.resetTo(startTime);
w.value().reset();
return w;
}
}
MetricsLeapArray
貌似也只是重写了部分方法,核