滑动窗口和固定窗口初看没啥区别啊

6次阅读
没有评论

直觉很敏锐!如果只看“正常流量”,它们确实没区别。但在**高并发的极端临界点**,固定窗口会有一个致命的“两倍流量”漏洞,而滑动窗口就是为了打这个补丁。

我们可以用一个**“1秒限流 100 个请求”**的例子,瞬间看清它们的区别。

### 1. 固定窗口的“临界爆发”漏洞

固定窗口(Fixed Window)是按**自然秒**(1:00, 1:01, 1:02)来计数的。

* **场景**:
1. 在 `0.9s` 时,突然涌入 100 个请求。由于这是当前秒,通过。
2. 在 `1.0s` 时(下一秒刚开始),又涌入 100 个请求。由于是新的一秒,计数器清零,通过。
* **结果**:虽然每一秒都没超过 100,但在 `0.9s – 1.1s` 这**短短 200ms 内,系统顶住了 200 个请求**。
* **代价**:如果你的数据库瞬间只能扛 100 个,这双倍的突发流量会直接让系统**宕机**。

 

### 2. 滑动窗口是如何“打补丁”的?

滑动窗口(Sliding Window)不再死板地盯着自然秒,它把 1 秒拆成了很多**小格子**(比如 10 个 100ms 的格子),并且**窗口是动起来的**。

* **场景(同样的 0.9s)**:
1. 当你在 `1.1s` 发起请求时,滑动窗口会回看过去 1 秒(即 `0.1s – 1.1s`)内的总和。
2. 因为它发现 `0.9s` 那里的 100 个请求还在窗口范围内,所以 `1.1s` 的请求会被**直接拒绝**。
* **结果**:无论你从哪个时间点切开看,**过去任意 1 秒内的总量永远不会超过 100**。

 

### 3. 资深开发的底层思考:代价是什么?

既然滑动窗口更稳,为什么不全用它?因为它有**性能代价**:

1. **内存占用**:固定窗口只需要存一个 `Counter`(数字);滑动窗口需要存储每一个小格子的计数,格子越细,内存占用越多。
2. **计算复杂度**:每次请求进来,都要动态计算当前属于哪个格子,并聚合过去 N 个格子的总和。

### 🛠 总结对比

| 特性 | 固定窗口 | 滑动窗口 |
| :— | :— | :— |
| **实现难度** | 极简单 (一个 AtomicInteger) | 较复杂 (需要环形数组或列表) |
| **安全性** | **差** (存在 2 倍流量风险) | **好** (平滑限制,无临界问题) |
| **性能** | 极高 | 略低 (格子分得越细越慢) |
| **代表工具** | 简单 Nginx 配置 | **Sentinel** (底层核心算法) |

### 📉 状态同步
– **2026-03-30**:已通过“临界爆发”案例澄清了固定窗口与滑动窗口的本质差异及优劣。

**所以说,如果你做的业务对瞬间压力非常敏感(比如抢购),一定要用滑动窗口;如果只是简单的接口防刷,固定窗口也够用了。**

**既然聊到了格子的粒度,你想看看 Sentinel 是如何在代码里通过 `LeapArray`(跳跃数组)来高性能实现这种“格子滑动”的吗?**

正文完
 0
bdspAdmin
版权声明:本站原创文章,由 bdspAdmin 于2026-03-30发表,共计1186字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)