刨析限流的常用算法

前言

在高并发场景下,为避免系统被压垮,经常会采用限流的方式来控制流量,这对系统的稳定性和可靠性至关重要,限流有很多成熟的解决方案,例如Hystrix,今天不聊Hystrix,而是从限流的基本算法进行刨析,理解各算法的优劣和使用场景,常用的限流算法主要有以下几种:

  • 计数器法
  • 滑动窗口计数法
  • 漏桶算法
  • 令牌桶算法

计数器法

这种算法最简单,把时间划分为窗口,比如1分钟一个窗口,在一段窗口内只接受固定数量的请求,比如60个,到达窗口结束时重新开一个新窗口

image.png

这种方法最简单,当然也有个明显的问题,比如如下图1min~2min时间段内,如果之前都没请求只在最后10ms发生大量请求,此时通过限流机制确实只收了60个,但由于马上进入第二个窗口,又开始重新计数,马上又进入大量请求,相当与在一窗口和二窗口切换这段时间内进入了双倍120个请求,显然瞬间量超过预期

image.png

滑动窗口计数法

基于上述问题,滑动窗口计数法在计数法之上进行了改进,为了避免上述情况发生,时间窗口不再是固定的时间段,而是根据时间的流转动态的调整窗口,增加更小的粒度来拆分窗口,且窗口随着时间的移动而移动,说法略微抽象,举个例子,比如还是控制1分钟60个请求,再把一分钟划分为60小格,每一格一秒,那么每过一秒就可以把窗口向前推一秒,即窗口范围永远是1分钟前到当前时间

如下图同一场景下,01:59时进入60个请求,假设当前时间到了02:01,进来大量请求,此时实际的窗口为01:01~02:01,计数器判断出窗口内已大到最大请求量60所以直接触发了限流,也就是说直到02:59秒后采能接收新的请求

image.png

漏桶算法

这也是一个经典算法,它的工作原理类似于一个装满水的桶,水以恒定的速度从桶底的孔中流出。当有新的水流(数据包)进入桶时,如果桶还没有满,则水流会被接纳并逐渐流出;如果桶已经满了,则多余的水流会被溢出,从而达到限流的目的

image.png

这种算法明显的特点是可以严格控制固定时间接收请求的次数,缺点也很明显:太严格了,想想一个一般系统的并发处理量只是一个平均值,系统的并发处理能力受硬件网络等各种情况影响,哪有那么准确的数

使用漏桶算法,你如果把流出速率控制到极限比如每秒1000个,某时系统突然来了1000个请求,系统能勉强能正常处理,但紧接着下一个时间节点又来了1000个请求你就吃不消了,因为上1000个可能还没处理完,然后下一秒又来1000个结果系统慢慢就崩溃了

那怎么办,设小点,比如设500,那么假如突然在某个时间点来了1000个请求,前后并没有其它大量请求(比如并发场景),此时明明系统可以处理这1000个请求,却白白丢弃了500个。。。

所以漏桶算法适合比较有规律的请求数或处理能力,对突发流量场景非常不友好

令牌桶算法

令牌桶算法实现如下

  • 令牌生成:系统以一个恒定的速率向桶中添加令牌。
  • 桶的容量:桶有一个固定的容量,用于存储令牌。
  • 数据包处理:当数据包到达时,需要从桶中获取一个令牌。如果有可用的令牌,则数据包被处理;如果没有足够的令牌,则数据包被延迟或丢弃。
image.png

令牌桶算法就太适合上述场景了,有一个最大令牌数应对突发流量,有一个令牌添加速度来控制流量,在上述场景下,可以把令牌数设为1000,这样在突发1000请求时由于之前没有大量请求积累了很多令牌,因此1000个请求大部分都被接收,而令牌耗尽后有一定的生成频率,又可以防止下一秒又来1000个干崩系统

其实令牌算法更符合系统的实际处理能力,即可以再空闲状态下瞬间处理大量请求,但处理这些请求的需要一段时间,所以不能长期处理这么大量的请求

就好比线程池有核心线程和最大线程,就是为了不浪费资源同时又能处理瞬间的高并发,令牌桶的涉及有异曲同工之妙,而漏桶算法的容量则是为了避免消费积压,实际关键的数据只有流出速率

总结

以上就是常见的限流算法,要说哪个好,只能说没有最合适的技术,只有最合适的场景,结合实际场景选择才是最理智的,而每一种结合场景都是个比较难的话题,而每种算法只是尽量合理不能做到绝对合理

扩展

我仔细想了下现实世界是如何实现限流的,马上就想到了一个最适当的场景:医院看病,医院看病时医院当然也要限流,因为每个诊室外面占不了那么多人排队啊,所以都是在外面等着叫号,叫完号再去里面排队,而他是怎么限流的? 他没有固定的算法(就像上面说的每个算法都并不玩们),一般是有个护士看门口排队的情况,如果人少了就放一些号进去排队,这是一种根据实际处理情况决定如何控制流量的方式,我想起软件界的一个词:背压,那如果限流是根据实际处理能力来实时决定如何限流,是不是更为合理,但这样做代价很大,现实中需要个人力一直观察,代码里就需要一个很复杂的逻辑实时监控处理进度

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容