当前位置: 首页 > 科技观察

Sentinel中的冷启动限流算法

时间:2023-03-13 15:05:17 科技观察

是基于令牌桶算法实现的。令牌桶算法的原理是:按照一定的速率向令牌桶中放入令牌,当收到请求时,从令牌桶中申请令牌,只有拿到令牌的请求才能通过。当令牌桶满时,多余的令牌将被丢弃;当令牌桶为空时,如果无法获取到令牌,请求将被拒绝。比如你想使用令牌桶算法限制接口的最大QPS为200,那么你需要每隔5毫秒产生一个令牌放入令牌桶,产生令牌的速度保持不变。冷启动算法用于控制令牌桶的令牌生产率,即控制每次令牌生产的时间间隔。假设冷启动时间为10秒,初始状态为冷启动状态,限流阈值为200QPS。正常情况下,出币速率应该是5毫秒/个,冷启动阶段,速率会从最小值增加到5毫秒/一个,最小速率与冷启动系数和长度有关的冷启动周期。Sentinel与Guava的实现不同。Sentinel可能是出于性能的考虑。它不控制每个请求的通过时间间隔,只控制每秒可以通过的请求数。使用下图来理解冷启动算法。坐标轴:横坐标storedPermits代表桶中令牌的数量;纵坐标表示获取令牌所需的时间,即请求通过的时间间隔;stableInterval:稳定生成token的时间间隔,假设限流阈值QPS为200,则stableInterval的值为5毫秒。coldInterval:冷启动生成token的最大时间间隔,等于稳定生成token的时间间隔乘以冷启动因子(stableInterval*coldFactor)。Sentinel中默认的coldFactor为3。warmupPeriod:预热时间,即冷启动时间,对应上图中的梯形区域,Sentinel中默认为10秒。thresholdPermits:令牌桶中令牌数量从冷启动到正常的阈值。当令牌桶中的令牌数量超过这个值时,进入冷启动阶段。由于coldFactor默认为3,(coldInterval-stableInterval)是stableInterval的两倍,所以thresholdPermits到0的时间是maxPermits到thresholdPermits时间的一半,也就是冷启动周期的一半。由于梯形的面积等于warmupPeriod,所以矩形的面积是梯形面积的一半,矩形的面积就是warmupPeriod/2。根据矩形面积公式:长*宽=面积:thresholdPermits=0.5*warmupPeriod/stableIntervalmaxPermits:桶中允许存储的最大令牌数。根据梯形的面积公式:(upperlow+lowerlower)*high/2可以得到:warmupPeriod=(stableInterval+coldInterval)*(maxPermits-thresholdPermits)/2发射:maxPermits=thresholdPermits+2*warmupPeriod/(stableInterval+coldInterval)slope:直线的斜率,即代币产生的速率。根据斜率计算公式:(y2-y1)/(x2-x1),可以得到:slope=(coldInterval-stableInterval)/(maxPermits-thresholdPermits)Sentinel每秒产生一次token,将新产生的token放入入订单卡桶,记录本次出币时间。下一次生产时,根据当前时间与上次生产令牌的时间间隔,以及每个令牌编号的生产间隔,计算本次需要生产的令牌。第一次启动服务时,或者长时间没有访问接口,当前时间会和上次生产token的时间相差很远,所以第一次生产token会生产maxPermits个token,直接放令牌桶已满。由于令牌桶已满,接下来的10s是冷启动阶段。由于冷启动阶段的token生产间隔比正常消费慢,随着时间的推移,桶中剩余的token数量会接近thresholdPermits,token生产间隔也会从coldInterval减少到stableInterval。当桶中剩余令牌数小于thresholdPermits时,冷启动结束,系统进入稳定状态。产生token的时间间隔为stableInterval,每秒产生的token数量等于QPS。Sentinel在请求通过时不会减少令牌桶中令牌的数量,而是在下一秒产生新的令牌时减去与前一秒通过的请求数量相等的令牌桶中的令牌数量。是Sentinel官方推出的自动掉币。每次请求通过时,Sentinel并不会从令牌桶中取令牌,那么Sentinel是如何控制QPS的呢?我们再看一张图:x1:当前令牌桶中超过thresholdPermits的令牌数;y1:y1加上stableInterval等于当前token生产的时间间隔;y1可以根据slope和x1计算:y1=slope*x1y1加上stableInterval就是当前的token生产率。当前秒内产生token的时间间隔为:slope*(storedTokens-thresholdPermits)+stableInterval因为:stableInterval=1.0(1秒)/限流阈值(count),所以上式=slope*(storedTokens-thresholdPermits)+1.0/Count最终计算出当前时间戳的QPS阈值:1.0/slope*(storedTokens-thresholdPermits)+1.0/count参考文献:[1]GuavaRateLimiter分析:https://blog.wangqi.love/articles/Java/Guava%20RateLimiter%E5%88%86%E6%9E%90.html本文转载自微信公众号“Java艺术”,可通过以下二维码关注。转载本文请联系爪哇艺术公众号。