阿里巴巴开源限流系统Sentinel-1.Metric埋点

Sentinel 埋点统计

Sentinel的核心就是围绕methos的执行状埋点统计信息,匹配预先设定degrade、folw……的规则。

1.Java Method状态

未引入熔断前,Java类Method运行,具有如下几个状态:

  • sucess
  • exception
  • rt
  • thread

引入Sentinel新增:

  • pass
  • block

对于web应用,某方法的RT增加,Thread也随之升高,单一资源持有线程资源不能及时释放势必影响其他功能点;另一点Exception,对于未捕获的异常,可以统计按照异常百分比进行降级操作。

2.实现原理

2.1滑动窗口

Sentinel基于跳跃数组实现了一个滑动窗口,每个Resource持有一个Node,Node内部是一个基于数组实现的滑动窗口,如下图。

上图是一个时间轮,其中有三个概念:

  • windowLength:一个窗口的长度,一个窗口即图中一个单元格时间跨度。
  • windownStart:窗口起始时间
  • interval:时间轮间隔,即一圈长度,运行一个周期后里面的数据即过期。

,每个单元格存储一个window对象,内部就是一个window对象数组。

例如:时间轮周期间隔interval=60秒,即1分钟,windowLength=1000ms,第一个窗口的windownStart:0,第二个窗口windownStart:1000,以此类推,参见具体代码 WindowWarp:

public class WindowWrap {
    /**
    * window滑动窗口长度.
    */
    private final long windowLength;
    /**
    * windown开始时间,单位milliseconds.
    */
    private long windowStart;
    /**
    * T泛型对象,即Window.
    */
    private T value;
}
复制代码

上面的泛型对象T就是Window,该对象持有Method的状态信息:sucess、pass,block,rt,exception等几个long类型的变量,作为计数器使用,参考代码如下。

0.2版本Windown改名为MetricBucket,换汤不换药,仅修改类名,代码仍然未变

public class Window {
    /**
     * 通过请求数,非熔断状态值为0
     */
    private final LongAdder pass = new LongAdder();
    /**
     * 熔断请求数
     */
    private final LongAdder block = new LongAdder();
    /**
     * 异常请求书,方法抛出Exception时被统计到。
     */
    private final LongAdder exception = new LongAdder();
    /**
     *  一个滑动窗口资源(方法)的总耗时
     */
    private final LongAdder rt = new LongAdder();
    /**
     * 成功数量
     */
    private final LongAdder success = new LongAdder();
    /**
     * 最小耗时,大于4900ms的被丢弃
     */
    private final LongAdder minRt = new LongAdder();
}
复制代码

2.2Node节点

Sentienl按照统计维度分为几种不同类型的Node,类图如下:

Node是一个接口,定义了一些列针对状态计数器的操作,StatisticNode作为实现类,结合上面提到的滑动窗口实现各个方法事件的实时统计。

public class StatisticNode implements Node {
    //秒级
    private transient Metric rollingCounterInSecond = new ArrayMetric(1000 / SampleCountProperty.sampleCount,
        IntervalProperty.INTERVAL);
    //分钟级
    private transient Metric rollingCounterInMinute = new ArrayMetric(1000, 2 * 60);
    //当前线程数,进方法+1,执行完毕-1
    private AtomicInteger curThreadNum = new AtomicInteger(0);
    //最后一次获取数据事件,下次获取的数据全在该时间后,即数据只能读取一次。
    private long lastFetchTime = -1;
}
复制代码

Node,StatisticNode的所有方法如下,方法执行前后埋点,调用:

3.结尾

上面简单介绍了资源状态统计的实现,后续介绍solt的过程,在结合Node一起详细介绍各种类型的Node的作用。

转载于:https://juejin.im/post/5c2f716a6fb9a049a62cb96e

你可能感兴趣的:(java)