最近写了一个限流的插件,因此避免不了的接触到了一些限流算法。本篇文章就来分析一下这几种常见的限流算法nginx
这个算法能够说是限流算法中最简单的一种算法了。git
核心思想github
计数器算法的意思呢就是当接口在一个时间单位中被访问时,我就记下来访问次数,直到它访问的次数到达上限。redis
涉及变量算法
条件一框架
当一个请求过来时,咱们就会获得这个key。分布式
1 2 3 4 5 6 7 8 9 |
if(存在key){ value++; if(value>=limit){ 不能访问 } }else{ 添加key,value为1 设置key过时时间为expire } |
条件二lua
既然条件一已经实现了,那条件二会复杂么 ?spa
相比于条件一来讲就是同一个key对应了多个用户。那么咱们只须要把key加上用户的信息就能够了。好比说 key_用户一、key_用户2。插件
核心思想
漏桶算法的意思呢就是一个接口在一个时间单位中容许被访问次数是动态变化的(假如一分钟容许访问60次,那么从开始计时时无论有没有被访问第59秒只容许访问59次,30秒只容许30次)。为何这样呢,由于有另一个线程在进行递减操做
涉及变量
条件一
线程一:
1 2 3 4 5 6 7 8 |
if(存在key){ value--; if(value<=0){ 不能访问 } }else{ 添加key,设置value为limit } |
线程二:
1 2 3 |
while(过去interval时间){ 全部key的value-step } |
条件二
参考计数器算法条件二实现。
算法升级
能够看到实现漏桶算法的话须要每隔interval时间都要另一条线程去遍历所key的value去作递减操做,那么有没有什么办法能够省略这一步呢。答案是确定有。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
if(存在key){ value--; if((nowTime-lastUpdateTime)>interval){ value=value-(nowTime-lastUpdateTime)/interval*step; lastUpdateTime=nowTime; } if(value<=0){ 不能访问 } }else{ 添加key,设置value为limit; lastUpdateTime=nowTime; } |
核心思想
令牌桶算法呢,偏偏是和漏桶算法相反的一个算法,不过仍是推荐你使用这个。这个算法的原理我不讲,我以为聪明的你看了伪代码就明白了。
涉及变量
条件一
线程一:
1 2 3 4 5 6 7 8 |
if(存在key){ value++; if(value>=limit){ 不能访问 } }else{ 添加key,设置value为limit } |
线程二:
1 2 3 |
while(过去interval时间){ 全部key的value+step } |
条件二
参考计算器算法条件二实现。
算法升级
参考漏桶算法升级实现。
代码实现请参考个人限流框架https://github.com/2388386839/syj-ratelimit
本文出自http://zhixiang.org.cn,转载请保留。