58

限制 API 请求的最佳方法是什么?基本上,我们希望将用户限制为每小时 360 个 API 请求(每 10 秒一个请求)。想到的是跟踪每个 API 请求和存储:

  ip-address          hourly-requests
  1.2.3.4             77
  2.3.4.5             34
  3.4.5.6             124

如果 ip-address 请求大于 360,只需返回一个标头:

  429 - Too Many Requests

然后每小时回滚计数器每小时请求。这似乎是一种非常低效的方法,因为我们必须对每个 API 请求进行 MySQL 查询以增加计数器。此外,我们需要一个 cron 任务来每小时重置所有计数器。

有没有更优雅/高效的解决方案?

4

5 回答 5

33

你可以尝试使用 Redis,速率限制的模式很少

于 2013-02-09T08:41:51.460 回答
13

我绝对不建议使用 MySQL 执行此操作 - 问题不在于读取次数过多或您在此处突出显示的算法效率低下 - 而是写入。随着数量的增加,您将开始进行多秒写入。我们使用 REDIS 作为存储,正如已经提到的另一张海报 - 它具有原子增量/减量功能,这正是您所需要的 + 它非常快(在内存中) - 您只需管理超高容量的分片(但超高是比 MySQL 高出许多数量级)。如果您不熟悉 REDIS,另一种选择是在 Memcached 中执行 - 但在操作级别上并没有那么好。

另一个选择仍然是使用 3scale (http://www.3scale.net) 之类的东西,它可以有效地为您 + 其他东西(分析、密钥管理、开发人员文档等)完成所有这些工作。有一大堆语言的代码插件(https://support.3scale.net/libraries),这些插件连接到基础设施。您还可以使用 Varnish Libmod (https://github.com/3scale/libvmod-3scale/) 并将其插入 API 前面的 Varnish 缓存中。

于 2012-06-03T08:01:40.033 回答
11

试试 nginx。通过在配置文件中编写简单的更改可以轻松完成速率限制。此外,nginx 速度很快。

于 2015-02-11T10:30:20.947 回答
7

为了获得理想的性能,您可以运行一个轻量级 Web 框架,该框架具有用于管理内存数据库上的日志的功能,用于监控和记录流量数据,无论是基于IP还是用户或用户调用的服务。更重要的选择是您要使用的数据存储。

最好和最常用的免费选项是:

redis.io高级键值存储

ehcache基于标准的缓存,作为一个专业的开源项目,由 Terracotta 积极开发、维护和支持

hazelcast一个开源内存数据网格,用于更快的执行和无缝的弹性可扩展性

VoltDB 内存操作数据库

于 2014-02-21T15:04:51.167 回答
2

我目前也在调查这个问题。我目前的计划(注意这是使用 LAMP 堆栈!)是使用 APC 的缓存功能来实现这一点。当收到请求时,我会检查该 IP 是否存储在 APC 的缓存中。如果是,则检查它是否大于“X”,其中“X”是每单位时间的最大请求数。如果不是,则为该 IP 创建缓存条目。

该系统意味着检查速率限制不需要数据库访问,并且它不依赖于 MongoDB 或 Redis 服务器之类的任何东西。它确实假设您将 PHP 与 APC 一起使用;如果你不是,那么 memcached 可能会起作用。

于 2012-03-05T05:10:50.633 回答