1 NodeSelectorSlot
作为责任链第一个节点会为当前资源获取到对应上下文的一个数据统计对象node,这允许了同一资源在不同上下文会有不同对应的数据统计对象。
并且通过context.getLastNode.addChild生成资源调用链条
2 LeapArray
滑动窗口实现类,将时间窗口分成若干个小窗口WindowWrap对象数组,根据当前时间/小窗口计算落在数组哪个索引元素,已存在即累加,不存在即新建,并记录开始时间。
计算时计算开始时间在时间窗口内的小窗口数组元素和
数组元素不变,数组元素代表的开始结束时间变化,类似环形数组
3 node
一个资源对应一个clusterNode
一个资源一个上下文对应一个defaultNode
4 StatisticNode.tryOccupyNext
在控流的时候会由defaultController调用。
当判断当前获取的令牌超过目前限值的时候就会尝试把令牌放在未来时间窗的某个样本窗口中,能添加成功并且等待执行的时间小于配置就会sleep后抛PriorityWaitException.
具体逻辑便是循环尝试将令牌放在未来样本窗口再计算未来的样本窗口流量是否达到流量,未达到流量则OK
5 FutureBucketLeapArray
未来的时间窗口计算由FutureBucketLeapArray计算,它重写了isWindowDeprecated,,样本窗口开始时间小于当前时间就会认为过期的。
6 限流类
DefaultController
默认限流类,利用滑动窗口统计请求是否超过阀值,超过了则尝试调用StatisticNode.tryOccupyNext,将请求置于未来的时间窗口
RateLimiterController
匀速限流类,运用漏桶匀速控制输出的原理,利用qps计算出请求的costTime,和上一次请求进行累加来计算当次请求期望通过的时间。
小于当前时间则直接通过,此处未计较并发。否则计算期望通过时间和当前时间是否大于最大等待时间,是的话则拒绝,否则sleep等待
WarmupController
带有预热算法的限流类,核心思想源于guava的rateLimiter,guava的rateLimiter在令牌不够时就会根据令牌产生速率进行等待,只不过guava可预支令牌,将本次请求应该等待的时间交由下次请求进行等待。
WarmupController则不一般,令牌处于预热阶段就会换算出qps,qps大于限制就会拒绝。否则则和设置正常qps比较
WarmupRateLimiterController
带有预热的匀速限流算法,预热阶段通过预热阀值qps计算costTime,再执行和RateLimiterController一样的逻辑