速率限制是许多开发人员可能在生活中某些时候必须处理的机制。它可用于多种用途,例如共享对有限资源的访问权限或限制对API端点的请求数量,并以429状态码进行响应 。
在这里,我们将探索一些使用Python和Redis的速率限制算法,从朴素的方法开始,最后达到一种称为通用单元速率算法(GCRA)的高级方法。
在以下文章中,我们将使用 redis-py 与Redis(pip install redis)通信。我建议您 从GitHub克隆 我的存储库,以进行一些限速实验。
时间桶
对一个请求中的请求数量进行速率限制的第一种方法 period 是使用时间分组算法,其中为每个速率密钥(诸如用户名或IP地址这样的唯一值)存储一个计数器(最初设置为 limit)和到期时间(period)并根据后续请求递减。
使用Python和Redis,我们可以通过以下方式实现时间桶逻辑:
检查价目码是否 key 存在
如果 key 不存在,则将其初始化为 limit 值(Redis SETNX)和到期时间 period (Redis EXPIRE)
在随后的每个请求中减小此值(Redis DECRBY)
仅当key 值降至零以下时,请求才受到限制
给定 period 密钥后将自动删除
from datetime import timedelta
from redis import Redis
def request_is_limited(r: Redis, key: str, limit: int, period: timedelta):
if r.setnx(key, limit):
r.expire(key, int(period.total_seconds()))
buck