15行Python代码带你轻松理解令牌桶算法

作者:simpleapples 时间:2021-05-05 01:18:05 

在网络中传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送,令牌桶算法就实现了这个功能, 可控制发送到网络上数据的数目,并允许突发数据的发送。

什么是令牌

从名字上看令牌桶,大概就是一个装有令牌的桶吧,那么什么是令牌呢?

紫薇格格拿的令箭,可以发号施令,令行禁止。在计算机的世界中,令牌也有令行禁止的意思,有令牌,则相当于得到了进行操作的授权,没有令牌,就什么都不能做。

用令牌实现限速器

我们用1块令牌来代表发送1字节数据的资格,假设我们源源不断的发放令牌给程序,程序就有资格源源不断的发送数据,当我们不发放令牌给程序,程序就相当于被限流,无法发送数据了。接下来我们说说限速器,所谓限速器,就是让程序在单位时间内,最多只能发送一定大小的数据。假设在1秒发放10块令牌,那么程序发送数据的速度就会被限制在10bytes/s。如果1秒内有大于10bytes的数据需要发送,就会因为没有令牌而被丢弃。

改进限速器——加个桶

15行Python代码带你轻松理解令牌桶算法 

我们实现的限速器,速度是恒定的,但是在实际的应用中,往往会有突发的传输需求(需要更快速的发送,但是不会持续太久,也不会引起网络拥塞),这种数据碰上我们的限速器,就因为拿不到令牌而无法发送。

对限速器进行一下改动,依然1秒产生10块令牌,但是我们把产生出来的令牌先放到一个桶里,当程序需要发送的时候,从桶里取令牌,不需要的时候,令牌就会在桶里沉淀下来,假设桶里沉淀了10块令牌,程序最多就可以在1秒内发送20bytes的数据,满足了突发数据传输的要求,并且由于桶里的令牌被用完,下一秒最多依然只能发10bytes的数据,不会因为持续发送大量数据,对网络造成压力。

15行Python代码带你轻松理解令牌桶算法 

15行Python代码实践令牌桶

令牌桶需要以一定的速度生成令牌放入桶中,当程序要发送数据时,再从桶中取出令牌。这里似乎有点问题,如果我们使用一个死循环,来不停地发放令牌,程序就被阻塞住了,有没有更好的办法?

我们可以在取令牌的时候,用现在的时间减去上次取令牌的时间,乘以令牌的发放速度,计算出桶里可以取的令牌数量(当然不能超过桶的大小),从而避免循环发放的逻辑。

接下来看代码:


import time
class TokenBucket(object):
# rate是令牌发放速度,capacity是桶的大小
def __init__(self, rate, capacity):
 self._rate = rate
 self._capacity = capacity
 self._current_amount = 0
 self._last_consume_time = int(time.time())
# token_amount是发送数据需要的令牌数
def consume(self, token_amount):
 increment = (int(time.time()) - self._last_consume_time) * self._rate # 计算从上次发送到这次发送,新发放的令牌数量
 self._current_amount = min(
  increment + self._current_amount, self._capacity) # 令牌数量不能超过桶的容量
 if token_amount > self._current_amount: # 如果没有足够的令牌,则不能发送数据
  return False
 self._last_consume_time = int(time.time())
 self._current_amount -= token_amount
 return True

总结

以上所述是小编给大家介绍的15行Python代码带你轻松理解令牌桶算法网站的支持!

来源:https://juejin.im/post/5ab10045518825557005db65

标签:python,令牌桶,算法
0
投稿

猜你喜欢

  • 详谈配置phpstorm完美支持Codeigniter(CI)代码自动完成(代码提示)

    2023-09-06 14:34:52
  • php链式操作mysql数据库(封装类带使用示例)

    2023-05-25 02:58:22
  • python SQLAlchemy的Mapping与Declarative详解

    2022-12-04 02:48:37
  • Laravel操作redis和缓存操作详解

    2023-05-25 02:19:29
  • oracle-快速删除重复的记录

    2008-01-16 19:12:00
  • 快速图片链接批处理

    2007-02-03 11:39:00
  • 各个版本IE合集下载,共存无冲突

    2007-11-29 13:12:00
  • sql如何在线创建新表?

    2010-06-22 21:21:00
  • 把网页中的(电话,qq等数字)生成图片的ASP程序

    2011-04-11 10:40:00
  • 一个不错的网页拾色器

    2007-09-30 19:45:00
  • 使用Python的Scrapy框架编写web爬虫的简单示例

    2023-08-03 12:37:50
  • python计算时间差的方法

    2023-05-19 16:08:23
  • Python双端队列deque的实现

    2022-07-07 02:37:29
  • Python+Selenium+phantomjs实现网页模拟登录和截图功能(windows环境)

    2023-11-17 11:00:43
  • TXT.WORD文档下载另存为,而不是在浏览器中打开

    2007-10-25 11:43:00
  • 小谈用户身体语言的阅读经验

    2009-10-19 20:52:00
  • 符合网站标准的图片切换代码(天极软件)

    2008-02-20 08:23:00
  • Django框架基础模板标签与filter使用方法详解

    2022-10-25 18:14:43
  • 如何使用python实现模拟鼠标点击

    2022-07-07 21:46:57
  • 发布网站改版时的3要3不要

    2008-12-31 18:48:00
  • asp之家 网络编程 m.aspxhome.com