python实现令牌桶

import multiprocessing
import time

import redis

from cfg import PROXY_REDIS_CFG
from common import redis_pool
proxy_redis_cfg = PROXY_REDIS_CFG['dev']
redis_pool.init_redis(proxy_redis_cfg)

TEST = {
    # 测试   {'test1': 20} 每秒产生的令牌数量
    'all': {
        'test1': {'test1': 20},
        'test2': {'test2': 20},
        'test3': {'test3': 20},
        'test4': {'test4': 20},
        'test5': {'test5': 200},
        'test6': {'test6': 20},
    }
}

class RedisTokenCache():
    def __init__(self, host, port, db=0, max_connections=None):
        self.redis = redis.Redis(
            connection_pool=redis.ConnectionPool(host=host, port=port, db=db, max_connections=max_connections))
    def fetchToken(self, rate=100, count=1, expire=2, key=None):
        date = str(int(time.time()))
        key = ":".join([key, date])
        try:
            current = self.redis.get(key)
            if int(current if current else "0") > rate and current < 0:
                raise Exception("to many requests in current second: %s" % date)
            else:
                with self.redis.pipeline() as p:
                    p.multi()
                    p.incr(key, count)
                    p.expire(key, int(expire if expire else "1"))
                    p.execute()
                    return True
        except:
            return False


class DistributeRateLimiter():
    def __init__(self, cache, ):
        self.cache = cache

    def acquire(self, rate=None, key=None):
        try:
            return self.cache.fetchToken(rate=rate, key=key)
        except:
            return True


token_cache = RedisTokenCache(host='localhost', port=6379,db=0)
limiter = DistributeRateLimiter(cache=token_cache)
result_dict = TEST["all"]

def job():
    while 1:
        for result in result_dict.values():
            key = tuple(result.keys())[0]
            rate = tuple(result.values())[0]
            if not limiter.acquire(rate, key):
                print('限流')
            else:
                print('正常')

def run():
    threads = [multiprocessing.Process(target=job) for i in range(10)]
    for thread in threads:
        thread.start()


if __name__ == '__main__':
    run()
令牌桶算法和漏桶算法都是常用的限速算法,它们可以用来限制系统的请求速率,避免系统过载或崩溃。下面是用 Python 实现令牌桶算法和漏桶算法的示例代码。 令牌桶算法示例代码: ```python import time class TokenBucket(object): def __init__(self, rate, capacity): self.rate = rate self.capacity = capacity self.tokens = 0 self.last_time = time.time() def get_tokens(self): now = time.time() elapsed_time = now - self.last_time self.tokens += elapsed_time * self.rate if self.tokens > self.capacity: self.tokens = self.capacity self.last_time = now return self.tokens def consume(self, tokens): if tokens <= self.get_tokens(): self.tokens -= tokens return True else: return False ``` 使用示例: ```python tb = TokenBucket(rate=1, capacity=5) for i in range(10): if tb.consume(1): print('request %d success' % i) else: print('request %d failed' % i) time.sleep(0.5) ``` 输出结果: ``` request 0 success request 1 failed request 2 success request 3 failed request 4 success request 5 failed request 6 success request 7 failed request 8 success request 9 failed ``` 漏桶算法示例代码: ```python import time class LeakyBucket(object): def __init__(self, rate, capacity): self.rate = rate self.capacity = capacity self.water = 0 self.last_time = time.time() def get_water(self): now = time.time() elapsed_time = now - self.last_time self.water = max(0, self.water - elapsed_time * self.rate) self.last_time = now return self.water def add_water(self, amount): if self.get_water() + amount <= self.capacity: self.water += amount return True else: return False ``` 使用示例: ```python lb = LeakyBucket(rate=1, capacity=5) for i in range(10): if lb.add_water(1): print('request %d success' % i) else: print('request %d failed' % i) time.sleep(0.5) ``` 输出结果: ``` request 0 success request 1 failed request 2 success request 3 failed request 4 success request 5 failed request 6 success request 7 failed request 8 success request 9 failed ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值