Token Bucket(令牌桶算法)的实现——如何正确地限制网络流量

【史上最清晰的讲解】Token Bucket(令牌桶算法的实现)——如何正确地限制网络流量

请添加图片描述

(兴奋地)哥哥,你听说过"令牌桶"算法吗?它就像是我们小时候拉着绳子散步的游戏哦!今天Nova就给你讲讲这个有趣的算法,一起来学习如何限制网络流量吧~(眨眼)

(清了清嗓子)首先,我们来想象一下,你拉着一根绳子在直线上匀速前进。每次你想做点什么事情之前,都要先把绳子往自己这边拉一点点,这样你拖在身后的绳子就会变短。每次想做事情,你都重复这个动作。同时,如果你选择什么都不做,绳子会以固定的速度慢慢放长,直到恢复原来的最大长度。

(比划着手势)另一种理解方式是,如果你不去拉绳子,它会以固定速率自己展开,直到最大长度。但如果你一直拉绳子,最终会把整根绳子都拉到身边,这时你必须等它再慢慢展开一点,才能继续拉动。

(兴奋地)现在把直线换成时间轴,是不是就容易理解了呢?拉动一点绳子,就相当于消耗一个令牌;绳子的长度就是令牌桶的容量;绳子展开到最大长度的速率,就是令牌桶在没有令牌消耗时补充令牌的速率。你也可以一次性把绳子全拉过来,这就是算法允许的突发流量,之后就会被限制到绳子展开的速度,也就是令牌桶填充的速率。

(故作严肃)那么,让我们来深入理解一下令牌桶算法的每个要素:

  1. 绳子的长度,对应令牌桶的容量(token_capacity),表示桶中最多能存放多少令牌。

  2. 拉动绳子,相当于消耗令牌(consume)。每次想执行受限的操作,就要先消耗一定数量的令牌。

  3. 绳子的恢复速度,对应令牌的填充速率(token_rate)。令牌以固定速率添加到桶中,直到达到容量上限。

  4. 一次性将绳子全部拉到身边,相当于允许的突发流量(burst)。桶中累积的令牌可以允许短时间内超速执行操作。

(竖起食指)要实现令牌桶,最关键的是记录和更新上一次令牌消耗的时间戳(last_consume_time)。有了这个值,再结合当前时间,就可以计算出这段时间内新填充的令牌数。

(托腮沉思状)嗯,不过在多线程环境下,对last_consume_time的读写要注意线程安全哦。std::atomic就派上用场啦!

(兴致勃勃)接下来我们再扩展一下思路。令牌桶算法只是流量整形(traffic shaping)的一种实现方式,还有"漏桶算法"(leaky bucket)与之相似但又不同。它更强调严格的速率限制,而不是允许突发。所以根据不同的需求,我们要灵活选择算法。

(自信满满)掌握了算法原理,具体实现就是体力活啦。在我们的代码中,token_bucket类封装了核心逻辑,还提供了方便的接口。比如wait()函数,在令牌不足时会自动等待,让调用者编码更简单。

(意犹未尽)限流在分布式系统中也非常重要哦。比如限制API的调用频率,防止被恶意刷单;再比如给不同的客户端分配流量配额,保证服务质量。学好了这一招,你就能设计出更强大的系统!(握拳)

(比了个V字手势)(●’◡’●)ノ♥ 学习C++,Nova永远是你最可爱的小助手!要一起加油鸭!

[注:免费下载]
代码实现

代码用例

  • 18
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值