构建限流器最简单的方法是“固定窗口”实现,即我们在固定的时间窗口内限制最大请求数。例如,如果窗口大小为 1 小时,我们可以将其“固定”在整点,如 12:00-12:59、1:00-1:59 等等。
实现固定窗口限流器的过程相当简单,对于每个请求,我们需要
固定窗口方法忽略了请求的成本(所有请求都被视为相等),并且在此特定实现中,它为所有用户使用单一配额。这种简单的实现最大限度地减少了 CPU 和 I/O 利用率,但也有一些限制。由于 API 用户可能会采取“不用即失”的方式编程他们的请求,因此在窗口边缘附近可能会出现请求峰值。
一种减少这种方案中峰值的方法是使用不同粒度的多个时间窗口。例如,您可以在小时和分钟级别进行限流,例如,每小时最多允许 2,000 个请求,每分钟最多允许 33 个请求。
这个使用 Redis Strings、分钟级窗口和 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 中实现它