美文网首页
Redis 实战 - 控制访问频率

Redis 实战 - 控制访问频率

作者: 大鱼炖海棠 | 来源:发表于2019-07-21 20:46 被阅读0次

场景举例

我们日常上网冲浪的时候,常常会遇到这样的情景:

  • 多次输错登陆密码,再次尝试登录,页面提示需要输入正确的图形验证码
  • 某内容平台限定,每个账号单日可发布的文章数量不得超过规定上限
  • 采用短信验证码进行交互的场景,M分钟内请求的验证码次数过多,接下来的N分钟里会被拒绝请求,并提示"用户操作频繁,请稍后再试"

业务逻辑抽离

上述情景虽发生于多个业务场景下,但它们背后的需求本质是相同的,即如何通过控制用户的访问频率来限制恶意流量。这同一类问题在实现上具备相同的逻辑处理流程:


业务流程

对上述逻辑进一步抽象,可以得到解决问题的关键性元素:

  • 限流对象:用户
  • 限流操作:高频次请求,多次鉴权未通过等异常请求
  • 限流规则:由业务类型决定,如3分钟内请求短信验证码不得超过5次,如果触达上限,接下来的10分钟内拒绝该用户的所有请求,并警示

Redis 限流方案

基于 Redis 的 incr 原子操作,Expires key 过期机制,还有其内存数据库的效率优势,可以相对简单、高效的处理用户访问频率问题。

服务端在接收到用户请求时,首先根据用户发起的操作类型从 Redis 数据库中查询访问记录情况。如果是首次发起请求,则创建新键记录,访问次数记为1,并设置超时时间,以后该用户的每次请求都采用 INCR 命令递增该键的值。否则判断键值是否超出访问频率,如果没有就放行,否则跳转到限流处理逻辑。该键过期后被自动剔除,所以用户又可以正常发起请求。

这是非常容易想到的一种解决方案,但实际操作中会出现如下问题:假设某网站的限流规则是1分钟内的用户请求不能超过100次,这时用户发起了1次请求,1分钟计时开始,在这1分钟的最后1秒,用户发起了99次访问。因为 Redis 的 expires 机制,这个键值对在下一秒就被剔除,而用户在下一分钟的第1秒里又连续发起了99次访问,在系统看来这种走位是合法的,所以并不会加以限制,但却违背了初衷,我们所期望的限流其实是滑动时间窗口计数模式,而不是按照限流计时区间来切割时间。

(java代码待补充)

相关文章

网友评论

      本文标题:Redis 实战 - 控制访问频率

      本文链接:https://www.haomeiwen.com/subject/qxamlctx.html