在前文 《限流熔断是什么,怎么作,不作行不行?》中针对 “限流” 动做,有提到流量控制其内部对应着两种经常使用的限流算法,分别是漏桶算法和令牌桶算法。所以会有的读者会好奇,这都是些啥?git
为了更进一步的了解 WHY,本文来快速探索一下,看看限流下的一些 “算法” 们到底有何做用,是为什么成为流量控制的基石的?github
理论上每个对外/内提供功能的资源点,都须要进行必定的流量控制,不然在业务的持续迭代中,是有可能出现突发性流量的场景(就像年初所带来的一些行业突发转变,致使业务流量忽然暴增):算法
若没有进行限流,就会出现一些奇奇怪怪的问题点,实则就是系统没法承受这波流量,逐渐崩溃,走向系统假死。api
最多见的现实场景就是平常随处可见的排插、插座,其内置的保险丝,也被称为电流保险丝,其主要是起过载保护做用,保险丝会在电流异常升高到必定的高度和热度的时候,自身熔断切断电流,从而起到保护电路安全运行的做用。安全
所以真实世界中有许多与软件工程中的限流熔断的场景有殊途同归之处,也是为了控制量,超量就切断。你也能够想一想现实生活中是否有遇到其余相似的例子呢?网络
漏桶算法(Leaky Bucket)是网络中流量整形(Traffic Shaping)或速率限制(Rate Limiting)时经常使用的一种算法,它的主要目的是控制数据注入到网络的速率,平滑网络上的突发流量。架构
漏桶算法经过其算法调控了流量访问,使得突发流量能够被整形,去毛刺,变成一个相对缓和,以便为网络提供一个稳定的流量。框架
漏桶算法的存储桶主要由三个参数定义,分别是:桶的容量、水从桶中流出的速率、桶的初始充满度。微服务
其核心理念就如字面意思:一个会漏水的桶。spa
在上图中,水龙头表明着突发流量(Bursty Flow)。当网络中存在突发流量,且无任何调控时,就会出现像 Bursty Data 处相似的场景。主机以 12 Mbps 的速率发送数据,时间持续 2s,总计 24 Mbits 数据。随后主机暂停发送 5s,而后再以 2 Mbps 的速率发送数据 3s,最终总共发送了 6 Mbits 的数据。
所以主机在 10s 内总共发送了 30 Mbits 的数据。但这里存在一个问题,就是数据的发送并非平滑的,存在一个较大的波峰。若全部流量都是如此的传输方式,将会 “旱的旱死涝的涝死”,对系统并非特别的友好。
为了解决 Bursty Flow 场景的问题。漏桶(Leaky Bucket)出现了,漏桶具备固定的流出速率、固定的容量大小。
在上图中,漏桶在相同的 10s 内以 3 Mbps 的速率持续发送数据来平滑流量。若水(流量)来的过猛,但水流(漏水)不够快时,其最终结果就是致使水直接溢出,呈现出来就是拒绝请求/排队等待的表现。另外当 Buckets 空时,是会出现一次性倒入达到 Bucket 容量限制的水的可能性,此时也可能会出现波峰。
简单来说就是,一个漏桶,水流进来,但漏桶只有固定的流速来流出水,若容量满即拒绝,不然将持续保持流量流出。
令牌桶算法也是网络中流量整形或速率限制时经常使用的一种算法,它的主要目的是控制发送到网络上的数据的数目,并容许突发数据的发送。
令牌桶算法会以一个恒定的速率向桶里放入令牌,若是有新的请求进来但愿进行处理,则必需要先从桶内拿到一个可用的令牌,才能继续被处理。若桶内无令牌可取时,则拒绝请求/排队等待。
漏桶算法和令牌桶算法本质上都是为了作流量整形(Traffic Shaping)或速率限制(Rate Limiting),避免系统由于大流量而被打崩,但二者核心差别在于限流的方向是相反的。
令牌桶限制的是流量的平均流入速率,而且容许必定程度的忽然性流量,最大速率为桶的容量和生成 token 的速率。而漏桶限制的是流量的流出速率,是相对固定的。
所以也会相对的带来一个问题,在某些场景中,漏桶算法并不能有效的使用网络资源,由于漏桶的漏出速率是相对固定的,因此在网络状况比较好,没有拥塞的状态下,漏桶依然是限制住的,并无办法放开量。而令牌桶算法则不一样,其可以是限制平均速率的同时支持必定程度的突发流量。
在软件系统中,限流经常所表明的就是流量整形、速率限制,是一个很是常见的调控手段。通常咱们会将其在初期集成到统一框架、网关、Mesh 中去。所以建议接触业务的同窗,都要对这一块进行考量,便于后续的快速使用/接入,毕竟业务的流量爆发老是来的比较忽然,甚至多是恶意攻击。
而本文所提到的漏桶,令牌桶都是很是常见的手段,虽然二者独立出来分析了。但从软件开发的角度来说,你认为二者是否能够融合,结合其优点呢?
分享 Go 语言、微服务架构和奇怪的系统设计,欢迎你们关注个人公众号和我进行交流和沟通,二维码:
最好的关系是互相成就,各位的点赞就是煎鱼创做的最大动力,感谢支持。