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

2024-10-29 08:35:00
admin
原创
91
摘要:问题描述:我网站的合法用户偶尔会向服务器发送 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 中是否有同样的东西。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   681  
  在项目管理领域,集成产品开发(IPD)流程以其高效、协同的特点,被众多企业视为提升产品竞争力的关键。IPD流程强调跨部门、跨职能的紧密合作,以确保产品从概念到市场各个环节的无缝衔接。然而,实现这一目标并非易事,它需要企业深刻理解并掌握IPD流程中的跨部门协作艺术。本文将深入探讨IPD流程中跨部门协作的三个关键点,旨在为...
IPD项目管理咨询   9  
  掌握IPD流程图:提升团队协作的关键路径在当今快速变化的商业环境中,团队协作的效率与效果直接关系到项目的成功与否。集成产品开发(Integrated Product Development,简称IPD)作为一种先进的研发管理理念,通过跨部门、跨领域的协同工作,能够显著提升产品开发的速度与质量。而IPD流程图,则是这一理...
IPD流程阶段   9  
  IPD流程概述:理解其核心价值与实施背景集成产品开发(Integrated Product Development,简称IPD)是一种先进的产品开发管理理念,它强调跨部门协作、市场导向和快速响应变化的能力。IPD流程不仅关注产品本身的技术创新,更注重将市场、研发、生产、销售等各个环节紧密集成,以实现产品从概念到市场的高...
华为IPD是什么   7  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程以其跨部门协作、高效决策和快速响应市场变化的特点,被众多企业视为提升竞争力的关键。然而,实践IPD流程并非易事,项目管理中的种种错误往往阻碍了其效果的充分发挥。本文旨在深入探讨如何在实施IPD流程时避免这些常见错误,...
IPD框架   7  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用