如何限制我网站的 API 用户?

2024-10-29 08:35:00
admin
原创
221
摘要:问题描述:我网站的合法用户偶尔会向服务器发送 API 请求,导致不良结果。我想设置一个限制,即每 5 秒最多调用一次 API 或每分钟最多调用 n 次(尚未确定确切的限制)。我显然可以在数据库中记录每个 API 调用,并对每个请求进行计算,以查看它们是否超出限制,但每个请求的所有这些额外开销都会违背目的。我可...

问题描述:

我网站的合法用户偶尔会向服务器发送 API 请求,导致不良结果。我想设置一个限制,即每 5 秒最多调用一次 API 或每分钟最多调用 n 次(尚未确定确切的限制)。我显然可以在数据库中记录每个 API 调用,并对每个请求进行计算,以查看它们是否超出限制,但每个请求的所有这些额外开销都会违背目的。我可以使用哪些其他资源密集程度较低的方法来设置限制?我使用的是 PHP/Apache/Linux,仅供参考。


解决方案 1:

好吧,没有办法在不对服务器进行任何$last_api_request写入的情况下完成我所要求的操作,但我至少可以消除记录每个请求的麻烦。一种方法是使用“漏桶”节流方法,该方法仅跟踪最后一个请求( )和时间范围内请求数/限制的比率($minute_throttle)。漏桶永远不会重置其计数器(与每小时重置一次的 Twitter API 节流不同),但如果桶已满(用户已达到限制),他们必须等待n几秒钟让桶变空一点,然后才能发出另一个请求。换句话说,它就像一个滚动限制:如果在时间范围内有先前的请求,它们会慢慢从桶中漏出;只有当您填满桶时,它才会限制您。

此代码片段将$minute_throttle针对每个请求计算一个新值。我指定分钟$minute_throttle因为您可以为任何时间段添加节流阀,例如每小时、每天等……尽管添加多个节流阀很快就会让用户感到困惑。

$minute = 60;
$minute_limit = 100; # users are limited to 100 requests/minute
$last_api_request = $this->get_last_api_request(); # get from the DB; in epoch seconds
$last_api_diff = time() - $last_api_request; # in seconds
$minute_throttle = $this->get_throttle_minute(); # get from the DB
if ( is_null( $minute_limit ) ) {
    $new_minute_throttle = 0;
} else {
    $new_minute_throttle = $minute_throttle - $last_api_diff;
    $new_minute_throttle = $new_minute_throttle < 0 ? 0 : $new_minute_throttle;
    $new_minute_throttle += $minute / $minute_limit;
    $minute_hits_remaining = floor( ( $minute - $new_minute_throttle ) * $minute_limit / $minute  );
    # can output this value with the request if desired:
    $minute_hits_remaining = $minute_hits_remaining >= 0 ? $minute_hits_remaining : 0;
}

if ( $new_minute_throttle > $minute ) {
    $wait = ceil( $new_minute_throttle - $minute );
    usleep( 250000 );
    throw new My_Exception ( 'The one-minute API limit of ' . $minute_limit 
        . ' requests has been exceeded. Please wait ' . $wait . ' seconds before attempting again.' );
}
# Save the values back to the database.
$this->save_last_api_request( time() );
$this->save_throttle_minute( $new_minute_throttle );

解决方案 2:

您可以使用令牌桶算法来控制速率,该算法与漏桶算法类似。请注意,您必须在进程之间(或您想要控制的任何范围)共享桶的状态(即令牌数量)。因此,您可能需要考虑锁定以避免竞争条件。

好消息:我为你做了所有这些:带宽限制/令牌桶

use bandwidthThrottle    okenBucketRate;
use bandwidthThrottle    okenBucketTokenBucket;
use bandwidthThrottle    okenBucketstorageFileStorage;

$storage = new FileStorage(__DIR__ . "/api.bucket");
$rate    = new Rate(10, Rate::SECOND);
$bucket  = new TokenBucket(10, $rate, $storage);
$bucket->bootstrap(10);

if (!$bucket->consume(1, $seconds)) {
    http_response_code(429);
    header(sprintf("Retry-After: %d", floor($seconds)));
    exit();
}

解决方案 3:

最简单的解决方案就是每 24 小时为每个 API 密钥提供有限数量的请求,并在某个已知的固定时间重置它们。

如果他们的 API 请求用尽了(即计数器达到零或限制,取决于您计数的方向),则停止向他们提供数据,直到您重置计数器为止。

这样,他们就不会向你提出太多要求,这对他们最有利。

解决方案 4:

我不知道这个线程是否还活着,但我建议将这些统计数据保存在 memcached 等内存缓存中。这将减少将请求记录到数据库的开销,但仍能达到目的。

解决方案 5:

您说“每个请求的所有这些额外开销都会违背目的”,但我不确定这是否正确。目的不就是防止服务器受到攻击吗?这可能是我实现它的方式,因为它实际上只需要快速读取/写入。如果您担心性能,您甚至可以将 API 服务器检查外包给不同的数据库/磁盘。

但是,如果您想要其他选择,您应该查看mod_cband,这是一个旨在帮助带宽限制的第三方 Apache 模块。尽管它主要用于限制带宽,但它也可以根据每秒请求数进行限制。我从未使用过它,所以不确定您会得到什么样的结果。还有另一个名为 mod-throttle 的模块,但该项目似乎现已关闭,并且从未为 Apache 1.3 系列以上的任何版本发布过。

解决方案 6:

除了从头开始实施之外,您还可以查看 API 基础设施,例如 3scale ( http://www.3scale.net ),它可以进行速率限制以及许多其他功能(分析等)。它有一个 PHP 插件: https: //github.com/3scale/3scale_ws_api_for_php。

您还可以在 API 前面粘贴类似 Varnish 的东西,然后像那样进行 API 速率限制。

解决方案 7:

难道这不是通过会话就能简单完成的吗?

microtime()與比較$_SESSION['last_access_microtime']

解决方案 8:

在 node js 中,有一个名为expess-rate-limiter的包,它正好可以完成您想要完成的任务。

它限制了一段时间内的请求数量。我不知道 PHP 中是否有同样的东西。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1289  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审(TR,Technical Review)环节至关重要,它不仅是对技术方案的评估,更是激发创新思维、推动产品创新的关键节点。深入理解TR在IPD流程中的创新思维及其应用实践...
IPD流程中TR   9  
  IPD(Integrated Product Development)产品开发流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。它打破了传统产品开发过程中部门之间的壁垒,将市场、研发、生产、销售等各个环节有机整合在一起,形成一个高效协同的整体。通过这种方式,企业能够更快速、更精准地开发出满足市场需求的产品...
IPD管理流程   11  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审(TR,Technical Review)环节在整个IPD流程里占据着关键位置,对项目的成功有着深远影响。深入探讨TR与项目成功的关系,有助于企业更好地运用IPD流程,提升...
IPD项目管理   8  
  IPD研发管理体系旨在打破部门墙,实现跨部门协同,确保产品开发以市场和客户需求为导向,高效、高质量地推出满足市场需求的产品。在这一体系下,产品创新可拆解为三个关键步骤,它们环环相扣,共同推动企业的产品不断迭代升级,在激烈的市场竞争中占据优势。这三个步骤分别聚焦于洞察市场机会、规划产品战略以及执行开发与验证,每一步都蕴含...
IPD框架   10  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用