我如何扼杀我的网站的API用户? [英] How do I throttle my site's API users?

查看:258
本文介绍了我如何扼杀我的网站的API用户?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的网站的合法用户偶尔锤造成不良的后果API请求的服务器。我想提起的不超过一个极限说一API调用每5秒或n每分钟通话(还没有想出确切的限制还)。我能明显记录在数据库每个API调用,并做每个请求的计算,看看他们是否超过限制,但在每次请求所有这些额外的开销将是击败目的。什么是其他资源密集程度较低的方法,我可以用它来建立一个限制?我使用PHP /阿帕奇/ Linux的,对于它的价值。

The legitimate users of my site occasionally hammer the server with API requests that cause undesirable results. I want to institute a limit of no more than say one API call every 5 seconds or n calls per minute (haven't figured out the exact limit yet). I could obviously log every API call in a DB and do the calculation on every request to see if they're over the limit, but all this extra overhead on EVERY request would be defeating the purpose. What are other less resource-intensive methods I could use to institute a limit? I'm using PHP/Apache/Linux, for what it's worth.

推荐答案

好吧,有没有办法做我问没有的任何的写入服务器,但我至少可以消除记录每一个请求。一种方法是使用漏桶节流方法,它只跟踪上一次请求的( $ last_api_request ),并请求数的比率/限制时限( $ minute_throttle )。漏桶从来没有将它的计数器(不像Twitter的API的油门其重置每隔一小时),但如果桶已满(用户达到了极限),他们必须等待 N 秒对于水桶空一点点就可以使另一个请求之前。换句话说,它就像一个滚动限制:如果有时间框架内previous请求,他们正在慢慢渗出了桶;它只是限制你,如果你填写桶。

Ok, there's no way to do what I asked without any writes to the server, but I can at least eliminate logging every single request. One way is by using the "leaky bucket" throttling method, where it only keeps track of the last request ($last_api_request) and a ratio of the number of requests/limit for the time frame ($minute_throttle). The leaky bucket never resets its counter (unlike the Twitter API's throttle which resets every hour), but if the bucket becomes full (user reached the limit), they must wait n seconds for the bucket to empty a little before they can make another request. In other words it's like a rolling limit: if there are previous requests within the time frame, they are slowly leaking out of the bucket; it only restricts you if you fill the bucket.

这code段将计算在每次请求一个新的 $ minute_throttle 值。我指定的的在 $ minute_throttle ,因为你可以添加任何时间段的油门,如每小时,每天,等...虽然比一会快速启动,使其混乱的用户。

This code snippet will calculate a new $minute_throttle value on every request. I specified the minute in $minute_throttle because you can add throttles for any time period, such as hourly, daily, etc... although more than one will quickly start to make it confusing for the users.

$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 );

这篇关于我如何扼杀我的网站的API用户?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆