美文网首页基础原理
大型网站限流算法的实现和改造

大型网站限流算法的实现和改造

作者: Java学习录 | 来源:发表于2018-09-27 22:14 被阅读7次

最近写了一个限流的插件,所以避免不了的接触到了一些限流算法。本篇文章就来分析一下这几种常见的限流算法

分析之前

依我个人的理解来说限流的话应该灵活到可以针对每一个接口来做。比如说一个类里面有5个接口,那么我的限流插件就应该能针对每一个接口就行不同的限流方案。所以呢,既然针对的每个接口所以就需要一个可以唯一标示这个接口的key(我取的是类名+方法名+入参)。

分布式限流强烈推荐使用redis+lua或者nginx+lua来实现。

这里用2个限流条件来做示例讲一下常见的限流算法:

1. 接口1它10秒钟最大允许访问100次

2. 接口2它10秒钟最大允许每个人访问100次。

计数器算法

这个算法可以说是限流算法中最简单的一种算法了。

核心思想

计数器算法的意思呢就是当接口在一个时间单位中被访问时,我就记下来访问次数,直到它访问的次数到达上限。

涉及变量

1.接口(key)

2.时间单位(expire)

3.允许访问多少次(limit)

4.访问次数(value)

条件一

当一个请求过来时,我们就会得到这个key。

if(存在key){

       value++;

    if(value>=limit){

       不能访问

      }

}else{

    添加key,value为1

    设置key过期时间为expire

  }

条件二

既然条件一已经实现了,那条件二会复杂么 ?

相比于条件一来说就是同一个key对应了多个用户。那么我们只需要把key加上用户的信息就可以了。比如说 key_用户1、key_用户2。

漏桶算法

核心思想

漏桶算法的意思呢就是一个接口在一个时间单位中允许被访问次数是动态变化的(假如一分钟允许访问60次,那么从开始计时时不管有没有被访问第59秒只允许访问59次,30秒只允许30次)。为什么这样呢,因为有另外一个线程在进行递减操作

涉及变量

1.接口(key)

2.时间单位(expire)

3.允许访问多少次(limit)

4.递减间隔时间(interval)

5.递减步长(step)

6.剩余可访问次数(value)

7.key的访问时间(lastUpdateTime)

8.当前时间(nowTime)(注意nowTime的取值应为应用取得的时间而不是redis或者nginx取得的时间)

条件一

线程一:

if(存在key){

    value--;

    if(value<=0){

           不能访问

       }

}else{

    添加key,设置value为limit

  }

线程二:

while(过去interval时间){

    所有key的value-step

  }

条件二

参考计数器算法条件二实现。

算法升级

可以看到实现漏桶算法的话需要每隔interval时间都要另外一条线程去遍历所key的value去做递减操作,那么有没有什么办法可以省略这一步呢。答案是肯定有。

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.接口(key)

2.时间单位(expire)

3.允许访问多少次(limit)

4.递增间隔时间(interval)

5.递增步长(step)

6.当前可访问次数(value)

7.key的访问时间(lastUpdateTime)

8.当前时间(nowTime)(参照漏桶算法需要注意的点)

条件一

线程一:

if(存在key){

       value++;

    if(value>=limit){

          不能访问

      }

}else{

    添加key,设置value为limit

  }

线程二:

while(过去interval时间){

    所有key的value+step

  }

条件二

参考计算器算法条件二实现。

算法升级

参考漏桶算法升级实现。

代码

代码实现请参考我的限流框架https://github.com/2388386839/syj-ratelimit

本文出自http://zhixiang.org.cn,转载请保留。

相关文章

  • 大型网站限流算法的实现和改造

    最近写了一个限流的插件,所以避免不了的接触到了一些限流算法。本篇文章就来分析一下这几种常见的限流算法 分析之前 依...

  • 面试官:限流算法有哪些?

    限流的实现算法有很多,但常见的限流算法有三种:计数器算法、漏桶算法和令牌桶算法。 一、计数器算法 计数器算法是在一...

  • 基于Redis的限流系统的设计【转】

    基于Redis的限流系统的设计,主要会谈及限流系统中限流策略这个功能的设计;在实现方面,算法使用的是令牌桶算法来,...

  • 限流降级方案

    限流算法 并发数限流 计数器并发数限流:使用共享变量实现 信号量:使用java中的Semaphore QPS限流 ...

  • 限流框架系列之常见限流算法

    四种常见的限流算法 固定时间窗口限流算法 滑动时间窗口限流算法 令牌桶限流算法 漏桶限流算法 算法比较 算法确定参...

  • 关于限流算法

    转自:https://www.jianshu.com/p/76cc8ba5ca91 限流算法实现 常见的限流算法有...

  • 谷歌Guava限流工具RateLimiter

    基于guava-29.0版本。 RateLimiter是一个基于令牌桶算法实现的限流器,常用于控制网站的QPS。与...

  • 基于令牌桶算法的Java限流实现

    项目需要使用限流措施,查阅后主要使用令牌桶算法实现,为了更灵活的实现限流,就自己实现了一个简单的基于令牌桶算法的限...

  • SpringBoot基于RateLimiter+AOP动态的为不

    一 限流实现: RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技,并且根...

  • Guava RateLimiter限流

    缓存,降级和限流是大型分布式系统中的三把利剑。目前限流主要有漏桶和令牌桶两种算法。 缓存:缓存的目的是减少外部调用...

网友评论

    本文标题:大型网站限流算法的实现和改造

    本文链接:https://www.haomeiwen.com/subject/ubbyoftx.html