首页 > 其他分享 >Sentinel系列之滑动窗口、漏桶代码分析

Sentinel系列之滑动窗口、漏桶代码分析

时间:2023-10-04 18:12:25浏览次数:56  
标签:窗口 请求 限流 时间 滑动 Sentinel 漏桶

1. 滑动窗口

  • 原理

    滑动窗口限流算法(Sliding Window)是对固定窗口算法的一个改进。在滑动窗口算法中,窗口大小仍然是固定的,但它把单位时间周期划分为n个小周期,分别记录每个小周期内请求的数量,根据时间滑动删除过期的小周期。

    需要注意的是,当请求到达新的周期,才会往前滑动,也就是说滑动是在过了一个完整的窗口之后才开始的,不是立即开始,否则和固定窗口没什么区别。

image

  • Sentinel实现

    StatisticNode使用了滑动窗口算法统计指标,在DefaultController中被调用,作为默认的一种限流方式。(com.alibaba.csp.sentinel.slots.block.flow.TrafficShapingController是Sentinel的流量控制算法类,DefaultController是它的一个实现)

image

StatisticNode持有两个ArrayMetric对象,分别是以秒为单位和以分为单位的时间窗口。限流判断用的是第一个窗口,它是1秒钟的窗口,被分成了2个小周期。

image

ArrayMetric持有一个LeapArray对象,LeapArray是Sentinel里面一个指标度量的基类。

它拥有一个数组,protected final AtomicReferenceArray<WindowWrap> array; 存储一个个小周期的桶(Bucket),记录时间周期内请求的数据。

它有两种实现,我们先看BucketLeapArray.

  • BucketLeapArray

    image

    它的一个核心方法是com.alibaba.csp.sentinel.slots.statistic.base.LeapArray#currentWindow(),在很多操作中第一步都是定位到当前的窗口周期。

    具体实现如下:

    a. 根据传入时间(一般是当前时间)计算出对应窗口在数组中的下标和当前窗口开始的时间

    image

    b. 取出桶元素,分三种场景进行讨论

    image

    c. 如果桶不存在,直接创建并CAS设置。

    image

    d. 如果桶存在且开始时间相相等,说明桶没有过期,直接使用

    image

    e. 桶已经过期了,要清空并重新设置窗口开始时间。没有专门线程清理过期的桶。超过一个窗口之后,会重新从下标0开始填充。

    image

  • OccupiableBucketLeapArray

    Sentinel 1.5.0 对底层的滑动窗口统计结构进行了升级,添加了“占用”机制,允许在当前 QPS 已经达到限流阈值时,同个资源高优先级的请求提前占用未来时间窗口的配额数,等待到对应时间窗口到达时直接通过,从而可以实现“最终通过”的效果而不是被立即拒绝;而同个资源低优先级的请求则不能占用未来的配额,阈值达到时就会被限流。

    Sentinel 1.5.0 引入了 FutureBucketLeapArray,这是一种特殊的滑动窗口,仅维持当前时间以后的格子,从而可以用于统计未来被预先占用的配额数目。Sentinel 将普通的滑动窗口与 FutureBucketLeapArray 组合成可占用的滑动窗口 OccupiableBucketLeapArray,从而实现了“部分高优先级请求最终通过”的效果。

    https://sentinelguard.io/zh-cn/blog/sentinel-1-5-0-release.html

  • 优点

    简单易懂,精度高。

  • 缺点

    一旦到达限流后,请求都会直接暴力被拒绝,不够友好。

2. 漏桶

  • 原理

    漏桶算法(Leaky Bucket)是将请求放入一个有固定容量的“桶”中,桶内的请求以固定速率传出。当桶满时,新进入的请求将被丢弃。

    漏桶算法可以保证处理请求的速率恒定,从而有效防止流量激增导致的服务不稳定,有点类似生产者消费者模式。

    image

  • Sentinel实现

    Sentinel在com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController通过漏桶算法实现了匀速处理,也就是4.2的模式。

    它的实现方式是,把一个时间周期(一般是1秒)按允许通过的请求数,平均分成N个小区间,一个小区间内只允许有一个请求通过。

    也就是说,每个请求可以去抢占一个小区间,如果抢到了并且不用等待超过最大等待时间,那就排队,否则拒绝。而资源端每个小区间只会处理一个请求,在一个时间周期内处理的数量也是恒定的,这就达到了匀速的目的。

    具体步骤如下:

    a.使用一个字段latestPassedTime来记录当前请求已经发放到哪一个时间点

    b.在每次请求到来之时,先计算它需要消耗的时间costTime(即一个小区间的大小)

    c. latestPassedTime+costTime得出预期时间expectedTime

    d. expectedTime-currentTime得出等待时间waitTime

    e. 如果waitTime小于等于允许等待时间,则排队,否则直接拒绝

    需要注意的是,latestPassedTime不是指已经通过了请求的时间点,不一定是过去的时间,它表示的是当前被抢占的区间已经到哪个时间点了,请求可以抢占未来的区间。

    image

源码分析

image

标签:窗口,请求,限流,时间,滑动,Sentinel,漏桶
From: https://www.cnblogs.com/kingsleylam/p/17742533.html

相关文章

  • Sentinel系列之SlotChain、NodeSelectorSlot、ClusterBuilderSlot分析
    本文基于Sentinel1.8.6版本分析1.SlotChain我们从入口com.alibaba.csp.sentinel.SphU#entry(java.lang.String)开始分析。一路走读下来,会进入到这个方法com.alibaba.csp.sentinel.CtSph#lookProcessChain,查找该资源对应的SlotChain。接下来看如何构建这个SlotChain.Se......
  • Sentinel
    目录雪崩问题雪崩问题微服务调用链路中的某个服务故障满,引起整个链路中的所有微服务都不可用,这就是雪崩。解决方案:1.超时处理:设定超时时间,请求一定时间没有响应就返回错误信息,不会无休止等待2.舱壁模式:限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔......
  • springboot整合sentinel,sleuth
     1. 整合sentinel流控当需要对一个接口进行流量监控时可以使用springboot整合sentinel  (1)在common模块中导入依赖spring-cloud-starter-alibaba-sentinel;  (2)下载sentinel控制台并启动;  (3)配置sentinel控制台地址信息spring.cloud.sentinel.transport.dashboa......
  • Sentinel系列之流量控制及熔断降级示例
    关于Sentinel的介绍网上很多,不再复制粘贴。本文主要演示Sentinel的两个重点功能:流量控制和熔断降级。示例基于Sentinel1.8.6, 同时使用JMeter进行并发请求(Postman无法并发)。当然也可以通过main方法,但这样就无法重复触发,并且无法学习Sentinel与Spring框架的集成另外需要注意的......
  • 熔断、限流、降级 —— SpringCloud Alibaba Sentinel
    Sentinel简介Sentinel是阿里中间件团队开源的,面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性Sentinel提供了两个服务组件:Sentinel用来实现微服务系统中服务熔断......
  • 滑动平均滤波参考代码
    目录在CH592上可以运行,用来给RSSI滤波。由于RSSI一般是-100~-20之间的数值,故数组类型是有符号数。/********************缓存迭代**参数:uint8_tnum待加入的数值*uint8_t*data待处理的数组*uint8_tlen数组长度*/__HIGH_CODEv......
  • 154. 滑动窗口
    154.滑动窗口题目链接:154.滑动窗口-AcWing题库1、暴力枚举窗口大小为k序列长为n以求最小值为例f[i]表示以i结尾的窗口中的最小值f[i]=min(a[j]),i-k+1<=j<=ifor:i=1~nfor:j=i-k+1~if[i]=min(a[j])2、单调队列......
  • android 实现左右滑动和底部菜单切换Demo
    packagecom.tools.ttt;importstaticandroid.content.ContentValues.TAG;importandroid.content.pm.ActivityInfo;importandroid.content.res.Configuration;importandroid.os.Bundle;importandroid.util.Log;importandroid.view.MenuItem;importcom.googl......
  • 双指针法、滑动窗口法、螺旋矩阵
    1.双指针法解有序数组的平方1.1题目要求LeetCode977有序数组的平方题目内容:给你一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。示例1:输入:nums=[-4,-1,0,3,10]输出:[0,1,9,16,100]解释:平方后,数组变为[16,1,0,9,100]排序......
  • 从Android事件分发机制看滑动冲突解决方案
    事件分发机制从ViewGroup的dispatchTouchEvent入手publicbooleandispatchTouchEvent(MotionEventev){...finalbooleanintercepted;if(actionMasked==MotionEvent.ACTION_DOWN||mFirstTouchTarget!=null){fi......