我网站的合法用户偶尔会使用 API 请求攻击服务器,从而导致不良结果。我想设定一个限制,即每 5 秒不超过一次 API 调用或每分钟 n 次调用(尚未弄清楚确切的限制)。显然,我可以将每个 API 调用记录在数据库中,并对每个请求进行计算,看看它们是否超出了限制,但每个请求上的所有这些额外开销都会违背目的。我可以使用哪些其他资源密集度较低的方法来设置限制?我正在使用 PHP/Apache/Linux,因为它的价值。
好吧,没有办法做我要求的事情any写入服务器,但我至少可以消除记录每个请求。一种方法是使用“漏桶”限制方法,它只跟踪最后一个请求($last_api_request
)以及时间范围内请求数/限制数的比率($minute_throttle
)。漏桶永远不会重置其计数器(与 Twitter API 的节流阀每小时重置一次不同),但如果桶变满(用户达到限制),他们必须等待n
在他们可以发出另一个请求之前,桶要清空一点。换句话说,这就像一个滚动限制:如果在时间范围内有先前的请求,它们就会慢慢地从桶中泄漏;如果你把水桶装满,它只会限制你。
此代码片段将计算一个新的$minute_throttle
每个请求的价值。我指定了minute in $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 );
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)