构建速率限制器的最简单方法是在我们限制固定时间窗口内的最大请求数的“固定窗口”实现中。例如,如果窗口大小为 1 小时,我们可以将其“固定”在每小时的顶部,例如 12:00-12:59、1:00-1:59 等等。
实现固定窗口速率限制器的过程相当简单,对于每个请求,我们
固定窗口方法忽略了请求的成本(所有请求都是平等的),并且在此特定实现中,它对所有用户使用单个配额。这种简单的实现将 CPU 和 I/O 利用率降至最低,但这也带来了一些局限性。在窗口边缘可能会遇到峰值,因为 API 用户可能会以“用完即弃”的方式编写他们的请求。
最小化此方案中尖峰的一种方法是拥有多个不同粒度的时段窗口。例如,您可以按小时和分钟级别进行速率限制,例如,允许每小时最多 2,000 个请求,每分钟最多 33 个请求。
使用 Redis 字符串、分钟大小的窗口和 20 个请求的配额的基本方法概述在 Redis 博客上。在跳入我们的 Spring Reactive 实现之前,我将在此处对其进行总结。
GET [user-api-key]:[当前分钟数]
例如 GET "u123:45"
MULTI
和 EXEC
)增加键并将到期时间设置为未来 59 秒。MULTI
INCR [user-api-key]:[current minute number]
EXPIRE [user-api-key]:[current minute number] 59
EXEC
5. 否则,满足请求。
好的,现在我们知道了基本方法,让我们在 Spring 中实现它。