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


Posted in Python onMarch 21, 2018

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

什么是令牌

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

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

用令牌实现限速器

我们用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代码带你轻松理解令牌桶算法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python中的闭包总结
Sep 18 Python
Python中pygame的mouse鼠标事件用法实例
Nov 11 Python
实例讲解Python中SocketServer模块处理网络请求的用法
Jun 28 Python
Python 中的lambda函数介绍
Oct 10 Python
Python提取支付宝和微信支付二维码的示例代码
Feb 15 Python
Python完成毫秒级抢淘宝大单功能
Jun 06 Python
Python解释器及PyCharm工具安装过程
Feb 26 Python
利用python对excel中一列的时间数据更改格式操作
Jul 14 Python
浅谈django不使用restframework自定义接口与使用的区别
Jul 15 Python
Python实现Canny及Hough算法代码实例解析
Aug 06 Python
重构Python代码的六个实例
Nov 25 Python
pytorch __init__、forward与__call__的用法小结
Feb 27 Python
Python反转序列的方法实例分析
Mar 21 #Python
Python常见工厂函数用法示例
Mar 21 #Python
python如何统计序列中元素
Jul 31 #Python
python如何读写json数据
Mar 21 #Python
python如何读写csv数据
Mar 21 #Python
python如何让类支持比较运算
Mar 20 #Python
python如何为创建大量实例节省内存
Mar 20 #Python
You might like
PHP-Fcgi下PHP的执行时间设置方法
2013/08/02 PHP
php调整gif动画图片尺寸示例代码分享
2013/12/05 PHP
Laravel中扩展Memcached缓存驱动实现使用阿里云OCS缓存
2015/02/10 PHP
PHP翻页跳转功能实现方法
2020/11/30 PHP
php使用CutyCapt实现网页截图保存的方法
2016/10/03 PHP
php中替换字符串函数strtr()和str_repalce()的用法与区别
2016/11/25 PHP
js输出阴历、阳历、年份、月份、周示例代码
2014/01/29 Javascript
如何获取网站icon有哪些可行的方法
2014/06/05 Javascript
javaScript基础语法介绍
2015/02/28 Javascript
基于HTML模板和JSON数据的JavaScript交互(移动端)
2016/04/06 Javascript
学习Bootstrap滚动监听 附调用方法
2016/07/02 Javascript
基于Bootstrap框架菜鸟入门教程(推荐)
2017/09/17 Javascript
详解设置Webstorm 利用babel将ES6自动转码成ES5
2017/12/20 Javascript
vue2 mint-ui loadmore实现下拉刷新,上拉更多功能
2018/03/21 Javascript
默认浏览器设置及vue自动打开页面的方法
2018/09/21 Javascript
vuex存储token示例
2019/11/11 Javascript
Echarts实现多条折线可拖拽效果
2019/12/19 Javascript
js利用iframe实现选项卡效果
2020/08/09 Javascript
[01:37]DOTA2超级联赛专访ChuaN 传奇般的电竞之路
2013/06/19 DOTA
[15:28]DOTA2 HEROS教学视频教你分分钟做大人-剧毒术士
2014/06/13 DOTA
[02:34]2016完美“圣”典风云人物:BurNIng专访
2016/12/10 DOTA
利用python求相邻数的方法示例
2017/08/18 Python
Python3 中把txt数据文件读入到矩阵中的方法
2018/04/27 Python
Python ini文件常用操作方法解析
2020/04/26 Python
如何在Anaconda中打开python自带idle
2020/09/21 Python
python 绘制正态曲线的示例
2020/09/24 Python
纯CSS3实现带动画效果导航菜单无需js
2013/09/27 HTML / CSS
HTML5 canvas 基本语法
2009/08/26 HTML / CSS
Waterford加拿大官方网站:世界著名的水晶杯品牌
2016/11/01 全球购物
美国婚礼和派对礼品网站:Kate Aspen(新娘送礼会、迎婴派对)
2018/03/28 全球购物
意大利网上书店:LaFeltrinelli
2020/06/12 全球购物
小学教师的个人自我鉴定
2013/10/24 职场文书
优秀生推荐信范文
2013/11/28 职场文书
工程总经理工作职责
2013/12/09 职场文书
幼儿园父亲节活动方案
2014/03/11 职场文书
银行竞聘上岗演讲稿
2014/09/12 职场文书