gpt4 book ai didi

php - 用redis实现防洪

转载 作者:IT王子 更新时间:2023-10-29 05:57:33 25 4
gpt4 key购买 nike

我正在尝试用基于 redis 的实现替换 Drupal 8 的防洪服务的 sql 实现。

参见 https://github.com/drupal/drupal/blob/8.0.x/core/lib/Drupal/Core/Flood/DatabaseBackend.php

要求是这样的:

  • 每次发生的 Action /事件(例如尝试登录)都记录有到期时间、标识符和时间戳
  • 我需要能够防止某个 Action 在给定时间范围内执行超过 N 次
  • 我希望能够清理过期的事件
  • 在 10 分钟内阈值为 3 的情况下,如果用户尝试一次,然后在 5 分钟后尝试两次,他将被阻止并且可以在再过 5 分钟后重试一次。不是 10。虽然第二种方法是执行此操作的有效方法,但它不是 sql 实现的工作方式或测试期望它如何工作的方式。
  • 根据API可以看出,我在注册事件时也不知道阈值是多少,我只知道单个事件的过期时间。

我对如何实现这个的想法:

  • 如果在给定时间内锁定 N 次事件之后,那么使用事件的单个 KEY 将很容易:递增的标识符,一旦达到最大值,它就会被锁定,直到它再次过期并且每个 INCR 都会也更新到期时间(或不更新)。
  • 我发现很多帖子都询问列表条目的到期时间,这是不可能的。有使用排序集和按范围删除的变通方法。大多数似乎都使用单个全局集,但我无法轻松计算我的事件 + 标识符 - 我认为。

在写下所有这些之后,我可能真的知道它是如何工作的,所以我想我正在寻找的是关于这是否有意义或者是否有更简单的方法的反馈。

每个事件:标识符组合都是一个键并包含一个排序集。这使用过期作为分数和值作为唯一值,可能以微秒为单位的创建时间。我计算未过期的记录以检测是否达到阈值。我正在更新每个事件的到期时间:标识符到提供的到期窗口,因此假设除非给定的标识符/客户端不放弃并继续尝试,直到没有达到到期时间,否则它将被自动删除。清理集合中的记录是否值得,例如什么时候做新登记?好像挺快的,我也只能偶尔做一下。

最佳答案

我更愿意使用 Redis 的 key 过期功能,而不是重新实现一个。

一个更简单的替代方案是以下一个:

  • 只需设置一个简单的值,即尝试次数;使用建立在类似 "identifier":"event type"模式之上的键:
    SETNX <identifier>:<event type> 1
  • 如果响应为 1,则这是第一次尝试,因此您在此键上设置超时:
    EXPIRE <identifier>:<event type> <timeout in seconds>

  • 否则你会增加尝试次数
    INCR <identifier>:<event type>
    INCR 的响应将为您提供窗口期间的尝试次数,以便您了解是否可以允许该操作。

如果您需要存储更多数据,例如给定时间窗口内允许的最大尝试次数,您也可以使用散列而不是简单值。在这种情况下,您可能会使用 HSETNX 和 HINCR。

关于php - 用redis实现防洪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34537428/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com