Token Bucket 算法

栏目: 编程工具 · 发布时间: 5年前

内容简介:最近在看celery代码,看到worker的代码,发现了tocket bucket算法,自己之前还一直 在想像有些API对调用次数有限制是怎么做到的,看完才发现,原来是这么朴素的算法。 真是无知,无知啊。嗯,以后要多读读源码。celery外链里但是写上了注释的代码(稍微做了一些改动):.. code:: python

最近在看celery代码,看到worker的代码,发现了tocket bucket算法,自己之前还一直 在想像有些API对调用次数有限制是怎么做到的,看完才发现,原来是这么朴素的算法。 真是无知,无知啊。嗯,以后要多读读源码。

celery外链里但是写上了注释的代码(稍微做了一些改动):

.. code:: python

# coding: utf-8 import time

class TokenBucket(object):
    def __init__(self, tokens, fill_rate):
        """tokens is the total tokens in the bucket. fill_rate is the
        rate in tokens/second that the bucket will be refilled."""
        self.capacity = tokens  # 桶的容量
        self._tokens = tokens  # 令牌们
        self.fill_rate = fill_rate  # 每秒放入的令牌数量
        self.timestamp = int(time.time())  # 上次请求令牌的时间

    def consume(self, tokens):
        """Consume tokens from the bucket. Returns True if there were
        sufficient tokens otherwise False."""
        if tokens <= self.__get_tokens():
            self._tokens -= tokens
        else:
            return False
        return True

    def __get_tokens(self):
        now = int(time.time())
        if self._tokens < self.capacity:
            delta = self.fill_rate * (now - self.timestamp)
            self._tokens = min(self.capacity, self._tokens + delta)
            print("delta: %s" % delta)
        self.timestamp = now
        return self._tokens

if __name__ == "__main__":
    bucket = TokenBucket(80, 1)
    print("tokens = %s" % bucket._tokens)
    print("consume(10) = %s" % bucket.consume(10))
    print("consume(10) = %s" % bucket.consume(10))
    time.sleep(1)
    print("tokens = %s" % bucket._tokens)
    time.sleep(1)
    print("tokens = %s" % bucket._tokens)
    print("consume(90) = %s" % bucket.consume(90))
    print("tokens = %s" % bucket._tokens)
    print("consume(90) = %s" % bucket.consume(90))
    print("tokens = %s" % bucket._tokens)

我们看一下测试结果:

.. code:: bash

$ python token_bucket.py
tokens = 80
consume(10) = True
delta: 0
consume(10) = True
tokens = 60
tokens = 60
delta: 2
consume(90) = False
tokens = 62
delta: 0
consume(90) = False
tokens = 62

最后我们用大白话来描述一下上面的代码:

1,初始化的时候,指定了桶的大小和每秒钟放入令牌的速率

2,每次消耗令牌的时候,都会计算,上次消耗到本次消耗之间产生了多少令牌,如果产生 令牌的数量超过了容量,则丢弃多余的令牌。

3,如果要消耗的令牌数量大于现有的令牌数量,则返回失败。

.. [#] https://en.wikipedia.org/wiki/Token_bucket

.. [#] http://code.activestate.com/recipes/511490/


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python高级编程(第二版)

Python高级编程(第二版)

[波兰] Michał Jaworski、[法] Tarek Ziadé / 张亮、阿信 / 人民邮电出版社 / 2017-9-19 / 89.00元

Python作为一种高级程序设计语言,凭借其简洁、易读及可扩展性日渐成为程序设计领域备受推崇的语言之一。 本书基于Python 3.5版本进行讲解,通过13章的内容,深度揭示了Python编程的高级技巧。本书从Python语言及其社区的现状开始介绍,对Python语法、命名规则、Python包的编写、部署代码、扩展程序开发、管理代码、文档编写、测试开发、代码优化、并发编程、设计模式等重要话题......一起来看看 《Python高级编程(第二版)》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具