返回

揭秘 Sentinel 滑动窗口限流的实现奥秘

后端

Sentinel 是一个深受青睐的轻量级流量控制框架,其精妙的滑动窗口限流机制在维护分布式服务的稳定性方面发挥着至关重要的作用。本文将深入解析 Sentinel 滑动窗口限流的实现,为读者揭开其幕后的技术奥秘。

滑动窗口限流简介

滑动窗口限流算法通过将一段时间内(窗口期)的请求划分为一个个窗口,对每个窗口内的请求进行计数和控制。当窗口内的请求数达到或超过设定的阈值时,则触发限流机制,拒绝后续的请求。这种算法既可以实时响应流量变化,又可以避免瞬时流量激增对系统的冲击。

Sentinel 滑动窗口限流实现

Sentinel 的滑动窗口限流实现主要依赖于一个叫 "SlidingWindowTrafficShapingController" 的类。该类维护着一个循环数组,其中每个元素代表一个窗口。数组的长度对应于窗口期,即 Sentinel 默认的 1 秒。

当一个请求到来时,SlidingWindowTrafficShapingController 会先将当前时间戳除以窗口期得到窗口索引,然后对该窗口内的请求计数进行加 1 操作。如果请求计数超过了设定的阈值,则触发限流。

核心数据结构:环形队列

Sentinel 滑动窗口限流的巧妙之处在于它使用了一个环形队列来存储窗口信息。环形队列是一种先进先出(FIFO)的数据结构,其尾部和头部相连,形成一个循环。

在 Sentinel 的实现中,环形队列的每个元素包含两个字段:请求计数和时间戳。当一个窗口期结束时,Sentinel 会将环形队列的头部出队,并将该窗口的信息丢弃。这确保了窗口始终代表最新的流量情况。

实例解析

假设 Sentinel 的窗口期为 1 秒,阈值为 100。现在有一个请求在 0.5 秒时到达,则其窗口索引为 0。SlidingWindowTrafficShapingController 将窗口 0 的请求计数加 1,变为 1。

如果在接下来的 0.5 秒内有 99 个请求到达,则窗口 0 的请求计数将增加到 100。此时,Sentinel 会触发限流,拒绝后续的请求,直到窗口 0 结束。

技术指南

使用 Sentinel 的滑动窗口限流机制非常简单。只需要在你的代码中添加以下代码:

// 限流规则,限流阈值为 100
FlowRule rule = new FlowRule("my_resource")
    .setCount(100);

// 注册限流规则
FlowController flowController = FlowRuleManager.loadRules(Collections.singletonList(rule));

// 限流逻辑
if (flowController.tryAcquire(1) == AcquireResult.SUCCESS) {
    // 允许请求执行
} else {
    // 触发限流,拒绝请求
}