认识
一、认识
削峰限流 是为了避免激增的大数据量、恶意用户访问等高并发数据导致的服务崩溃。假设说,有某一个时间点,突然间流量爆炸,无数的数据向服务器访问过来,这时如果没有一个削峰限流的策略,很可能会导致机器 Down
掉。所以说我们有必要去做一个削峰限流,从概率学的角度上讲,在大数据量的基础上我们对于整体数据做一个百分比的截断,并不会影响整体的一个数据比例。
削峰限流 有如下方案:
-
随机丢弃策略
-
流量整型策略
二、随机丢弃策略
前端做削峰限流最简单的方法是什么?没错,就是 Math.random()
,我们让用户传入一个采样率:
if(Math.random()<0.5) return;
非常简单的就实现了!但是这个方案不是一个很优雅的解决办法,为什么呢?
-
大流量项目限制了
50%
的流量,它的流量仍然多 -
小流量项目限制了
50%
的流量,那就没有流量了
三、流量整型策略
现在做流量整形的方法很多,最常见的就是三种:
-
计数器算法: 计数器算法就是单位时间内入库数量固定,后面的数据全部丢弃;缺点是无法应对恶意用户。计数器能够削峰,限制最大并发数以保证服务高可用
-
漏桶算法: 漏桶算法就是系统以固有的速率处理请求,当请求太多超过了桶的容量时,请求就会被丢弃;缺点是漏桶算法对于骤增的流量来说缺乏效率
-
令牌桶算法: 令牌桶算法就是系统会以恒定的速度往固定容量的桶里放入令牌,当请求需要被处理时就会从桶里取一个令牌,当没有令牌可取的时候就会据拒绝服务。令牌桶实现流量均匀入库,保证下游服务健康
最后我们团队在上述的方案选择中,最终选择了 计数器 + 令牌桶 的方案:
-
首先从外部来的流量是我们无法预估的,假设如我们有三个服务器
Pod
,如果总流量来的非常大,那么这时我们通过计数器算法,给它设置一个很大的最大值;这个最大值只防小人不防君子,可能99%
的项目都不会触发 -
这样经过总流量的计数器削峰后,再到中心化的令牌桶限流:通过
redis
来实现,我们先做一个定时器每分钟都去令牌桶里写令牌,然后单机的流量每个进来后,都去redis
里取令牌,有令牌就处理入库;没有令牌就把流量抛弃 -
这样子我们就实现了一个单机的削峰 + 中心化的限流,两者一结合,就是解决了小流量应用限流后没流量的问题,以及控制了入库的数量均匀且稳定