基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

Sentinel 的限流算法有哪些(如滑动时间窗口、漏桶、令牌桶)?

知识点图片

在 Alibaba Sentinel 中,限流(Flow Control)的设计非常精妙,它将 “统计”“控制” 进行了分离。

简单来说,Sentinel 底层的请求计数统一采用“滑动时间窗口”算法,而在面对超出阈值的流量时采取的管控策略(流控效果),则借鉴了“令牌桶”和“漏桶”算法的思想

以下是 Sentinel 中涉及的三大核心限流算法及对应机制的详细解析:


1. 滑动时间窗口算法(Sliding Time Window)—— 核心统计基础

在 Sentinel 中,所有的流量数据(如通过的 QPS、拒绝的 QPS、响应时间等)都是基于滑动时间窗口来统计的。

  • 实现机制:LeapArray 数据结构
    Sentinel 在底层实现了一个叫 LeapArray 的环形数组。它将一段时间(例如 1 秒)划分为多个极短的时间窗(Window Wrap / 样本窗口)。
    • 默认情况下,Sentinel 设定 1 秒作为一个滑动窗口(Interval),内部划分为 2 个时间跨度为 500ms 的样本窗口(Sample Count = 2)。
    • 随着时间的推移,当前时间指针向前滑动,废弃掉过期的时间窗,并创建一个新的时间窗来接收最新的流量。
  • 解决的问题:
    传统的“固定时间窗口”算法(比如直接按某一秒统计)存在临界突发问题(在第一秒的后半段和第二秒的前半段突然涌入大量请求,虽然单秒没超标,但两秒交界处的瞬间流量可能压垮系统)。滑动时间窗口通过更加平滑的滚动统计,完美解决了这个问题。

2. 快速失败(Fast Failure)—— 基于滑动窗口的直接拒绝

这是 Sentinel 默认的流控效果。

  • 工作原理:
    直接基于上述的“滑动时间窗口”统计出的当前 QPS。如果当前时间窗口内的 QPS(或并发线程数)已经超过了配置的阈值,那么新的请求就会立刻被拒绝,抛出 FlowException
  • 适用场景:
    对系统处理能力有明确认知,且希望在过载时直接丢弃多余请求以保护系统可用性的普通场景。

3. 匀速排队(Rate Limiter / Pacing)—— 基于“漏桶算法”(Leaky Bucket)

匀速排队模式是 Sentinel 对漏桶算法的具体实现。

  • 工作原理:
    漏桶算法的核心思想是“无论流入的速率有多快,流出的速率总是恒定的”
    在 Sentinel 中,它不关心当前系统的并发有多大,而是严格控制请求通过的时间间隔。例如,配置 QPS 为 10,那么 Sentinel 会严格限制每 100ms 只允许通过一个请求。
    • 当一个请求到来时,Sentinel 会计算它预期通过的时间。
    • 如果预期时间与当前时间的差值(等待时间)小于设置的超时时间,当前请求就会被阻塞休眠(Thread.sleep),排队等待通过。
    • 如果计算出的等待时间超出了设置的超时时间,则立即拒绝该请求。
  • 适用场景(削峰填谷):
    适用于处理突发性流量(脉冲流量)。例如在消息队列消费时,瞬间有几万条消息到达,通过匀速排队模式,可以让系统以固定速率(如每秒 1000 条)平滑地处理这些消息,防止系统瞬间被压垮。

4. 预热/冷启动(Warm Up)—— 基于“令牌桶算法”(Token Bucket)变种

Warm Up 模式借鉴了 Guava RateLimiter 中的平滑预热算法,其背后思想是令牌桶算法的变体

  • 工作原理:
    普通的令牌桶是以恒定速率生成令牌。而在预热模式下,令牌生成的成本(或消耗速率)是动态变化的
    • 当系统长期处于低负载或刚启动时,系统内部会积压大量“冷令牌”。
    • 当突然有大流量进来时,Sentinel 不会立刻允许达到设置的最高 QPS,而是从一个较低的初始水位开始放行。初始 QPS = 阈值 / coldFactor(默认 coldFactor 为 3,即从 1/3 的阈值开始)。
    • 在设定的预热时间(warmUpPeriodSec)内,系统逐渐“热”起来,放行的 QPS 阈值会平滑地增长,直到达到配置的最高 QPS。
  • 适用场景:
    适用于系统需要时间建立连接、加载缓存或预热数据库连接池的场景。防止系统刚启动或长期闲置后,被突发的大流量瞬间打满而宕机。

总结与对比

限流策略 (流控效果) 背后对应的核心算法 处理超出阈值流量的行为 最佳应用场景
直接拒绝 (Default) 滑动时间窗口 (计数) 直接抛出限流异常 (BlockException),迅速失败返回。 常规的系统过载保护。
匀速排队 漏桶算法 (Leaky Bucket) 让请求计算出等待时间进行休眠排队(削峰填谷),超时才拒绝。 突发流量脉冲,如秒杀瞬间、MQ消息突发堆积。要求平滑处理流量。
预热 (Warm Up) 令牌桶算法 (Token Bucket变体) 初始阈值极低,在指定时间内缓慢增加到最大阈值,超出动态阈值的拒绝。 系统刚启动或长期低峰,需要加载缓存/建立连接,防止冷启动被秒杀。

一句话总结:
Sentinel 用滑动时间窗口来“数”请求,而在“管”请求时:想要削峰填谷就配置匀速排队(漏桶),想要系统平滑启动就配置预热(令牌桶),想要简单粗暴保护系统就默认直接拒绝。

00:00
00:00