大萧条时期的野蛮生长——限流

140 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划·4月更文挑战」的第17天,点击查看活动详情

限流是后端系统的保护措施之一,和熔断降级类似,必要的时候需要丢卒保车,自断一臂。限流这个名词其实很形象了,水流猛如虎,大坝全开泄洪时下游的一切人类建筑都会毁于一旦,对应到后端服务也会陷入完全不可用状态。限流的作用就是挡住多余的请求,让系统承载范围内的请求顺利得到处理。下面简单介绍几种限流手段的原理。

固定窗口

这是相对比较低级的算法了,只记固定的时间窗口比如1分钟内的总请求,达到限制就丢弃。每分钟从0秒开始到59秒为一个固定的窗口,也可以按照秒来设定固定窗口。然后在一个通用存储内比如redis记下所有的请求,以此来限制流量。这样做的缺点是无法精确的限制不固定的流量,如果请求集中在50-59秒和0-10秒,那这20秒内的请求可能会超过设定的阈值,如果超过承载能力,那还是会引起系统不可用故障。

滑动窗口

相对于固定,那可以引入滑动窗口来解决动态流量的问题。0-59秒是一分钟,1-1秒(下一分钟的1秒)也是一份,这就是滑动窗口。这里需要将1分钟分成60个1秒,每一个1秒的请求独立计数,每一个1秒的请求会比对到上一分钟的这一秒,持续统计这个区间的请求数即可达到限流的目的。这比完全固定的窗口要灵活,相当于数学中的微分,把大问题拆成小问题,我们甚至可以拆到1毫秒为一个基本单位,但不能无限缩小,1毫秒时统计也无法做到精准了,持续的计算负担也很重。

很多文档都称这种算法为令牌桶,这里形象一点可以称之为入场券。比如1分钟只发100张入场券,无论一次有多少人来,什么时间段来,就一共只有100个,发完就没了,那这不就是固定窗口吗?这里还有一个机制,每1/100分钟我会增加一张入场券进去,保持桌子上时刻有券,但同时的总数永远不超过100个。这就从微分数学变成离散数学,其实也存在一定的性能问题和误差,获取入场券时肯定需要分布式锁,到临界点时必然会出现些许的超时,为了增加性能,最开始的时也会预置一定量的券在里面。