這裏是我是如何實現令牌桶的memcache上GAE:
編輯:以(另一個)刺傷此。
這部分地借用https://github.com/simonw/ratelimitcache/blob/master/ratelimitcache.py
def throttle(key, rate_count, rate_seconds, tries=3):
'''
returns True if throttled (not enough tokens available) else False
implements token bucket algorithm
'''
client = memcache.Client(CLIENT_ARGS)
for _ in range(tries):
now = int(time.time())
keys = ['%s-%s' % (key, str(now-i)) for i in range(rate_seconds)]
client.add(keys[0], 0, time=rate_seconds+1)
tokens = client.get_multi(keys[1:])
tokens[keys[0]] = client.gets(keys[0])
if sum(tokens.values()) >= rate_count:
return True
if client.cas(keys[0], tokens[keys[0]] + 1, time=rate_seconds+1) != 0:
return False
logging.error('cache contention error')
return True
下面是用法示例:
def test_that_it_throttles_too_many_requests(self):
burst = 1
interval = 1
assert shared.rate_limit.throttle('test', burst, interval) is False
assert shared.rate_limit.throttle('test', burst, interval) is True
def test_that_it_doesnt_throttle_burst_of_requests(self):
burst = 16
interval = 1
for i in range(burst):
assert shared.rate_limit.throttle('test', burst, interval) is False
time.sleep(interval + 1) # memcache has 1 second granularity
for i in range(burst):
assert shared.rate_limit.throttle('test', burst, interval) is False
不幸的是,你的反應不實現令牌桶速率限制爲每管理員的要求。請參閱https://github.com/bradbeattie/django-cache-throttle/blob/master/cache_throttle/utils.py,瞭解我的這種算法的Python實現,並參閱http://en.wikipedia.org/wiki/Token_bucket有關令牌桶的更多信息。 – 2014-04-08 18:33:44
呃,我把令牌桶的東西當作比需求更多的建議。此外,這主要是針對其他不需要令牌桶的人,因爲該頁面仍然是「App Engine費率限制」的頂級SERP。 出於好奇,令牌桶提供了什麼優勢比我的方法?它似乎能夠更好地處理「突發」,但是我還沒有想過其他優點嗎?只需稍作修改即可允許自定義速率限制鍵。 – 0x24a537r9 2014-05-07 04:47:29
是的,你是對的錢,因爲它主要是處理突發事件。假設你想在一天中允許用戶24行動。你可以將它們限制爲每小時一次,但是如果他們現在想要消耗24個,那麼它們就會使它們更加緊張。我認爲,令牌桶解決方案更符合預期的行爲。 – 2014-05-09 17:43:56