用Python标准库从零实现令牌桶限流器

举报
yd_263393080 发表于 2026/11/04 12:20:41 2026/11/04
【摘要】 不依赖第三方库,用threading和time实现线程安全的令牌桶限流器。

限流是后端避不开的话题。Python标准库里的threading和time就足够写出一个正确的令牌桶限流器。

一、令牌桶 vs 漏桶

漏桶输出速率恒定,令牌桶允许突发。对面向用户的接口,突发容忍更合理。

二、核心实现

惰性计算:记录上次补充时间,本次请求时根据时间差一次性补足。

import threading
import time

class TokenBucket:
    def __init__(self, rate, capacity):
        self.rate = rate
        self.capacity = capacity
        self.tokens = capacity
        self.last = time.monotonic()
        self.lock = threading.Lock()

    def acquire(self, need=1):
        with self.lock:
            now = time.monotonic()
            elapsed = now - self.last
            self.tokens = min(self.capacity, self.tokens + elapsed * self.rate)
            self.last = now
            if self.tokens >= need:
                self.tokens -= need
                return True
            return False

三、装饰器封装

def rate_limit(rate, capacity, on_reject=None):
    bucket = TokenBucket(rate, capacity)
    def deco(fn):
        def wrapper(*args, **kwargs):
            if bucket.acquire():
                return fn(*args, **kwargs)
            if on_reject is not None:
                return on_reject(*args, **kwargs)
            raise RuntimeError('rate limited')
        return wrapper
    return deco

四、并发细节

1. 用time.monotonic()不用time.time()。2. 锁要覆盖读-判-写整体。3. 不要sleep等待。

五、小结

整个实现不到50行,无第三方依赖,行为可预测。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。