美文网首页
常见限流方案设计与实现

常见限流方案设计与实现

作者: zfh_51d2 | 来源:发表于2020-07-26 22:40 被阅读0次

    前言

    当前负责一个社区项目的开发,所以总结一下当前项目的一些缺失的功能点。其中有一个便是限流,限流主要是通过对并发访问/请求进行限制或者一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务或者排队等待。

    为什么需要限流

    按照服务的调用方,可以分为以下几种类型服务

    1.与用户打交道的服务

    比如web服务、对外API,这种类型的服务有以下几种可能导致机器被拖垮:

    用户增长过快(这是好事)
    因为某个热点事件(微博热搜)
    竞争对象爬虫
    恶意的刷单
    这些情况都是无法预知的,不知道什么时候会有10倍甚至20倍的流量打进来,如果真碰上这种情况,扩容是根本来不及的。

    2.对内的RPC服务

    一个服务A的接口可能被BCDE多个服务进行调用,在B服务发生突发流量时,直接把A服务给调用挂了,导致A服务对CDE也无法提供服务。
    这种情况时有发生,解决方案有两种:
    1、每个调用方采用线程池进行资源隔离
    2、使用限流手段对每个调用方进行限流

    限流算法实现

    常见的限流算法有:计数器算法、漏桶算法、令牌桶算法等。

    1.计数器算法

    图片.png

    计数器算法主要是通过统计一段时间内的请求次数,当达到上限之后,剩下的请求则被丢弃或者做其他处理,当周期结束时则计数清零。例如:限制一分钟内请求次数60次,则在一分钟之内,每次请求,计数加一,当计数达到60之后的请求做其他处理。一分钟之后计数清零。

    计数器算法的实现比较简单,但这个算法有时会让通过请求量允许为限制的两倍。就说上面那个列子,假如在第一个一分钟的最后1秒收到了60个请求,之后计数清零,下一个一分钟的第一秒又收到了60个请求,这样看来就是在 2 秒中收到了120个请求。

    2.漏桶算法

    图片.png

    漏桶算法这个名字就很形象,算法内部有一个容器,类似生活用到的漏斗,当请求进来时,相当于水倒入漏斗,然后从下端小口慢慢匀速的流出。不管上面流量多大,下面流出的速度始终保持不变。不管服务调用方多么不稳定,通过漏桶算法进行限流,每10毫秒处理一次请求。因为处理的速度是固定的,请求进来的速度是未知的,可能突然进来很多请求,没来得及处理的请求就先放在桶里,既然是个桶,肯定是有容量上限,如果桶满了,那么新进来的请求就丢弃。

    在算法实现方面,可以准备一个队列,用来保存请求,另外通过一个线程池来定期从队列中获取请求并执行,可以一次性获取多个并发执行。

    漏桶算法的缺陷也很明显,当短时间内有大量的突发请求时,即便此时服务器没有任何负载,每个请求也都得在队列中等待一段时间才能被响应。

    3.令牌桶算法

    图片.png

    令牌桶算法和漏桶算法效果一样但方向相反的算法。系统会按固定的时间往桶里面添加令牌,如果桶已经满了就不再加。新请求来临时,会各自拿走一个令牌,如果没有令牌可拿了就阻塞或者做其他处理。这样即使短时间内突然访问量增加,也会在令牌用完之后才会做其他处理。

    令牌桶算法既能够将所有的请求平均分布到时间区间内,又能接受服务器能够承受范围内的突发请求,因此是目前使用较为广泛的一种限流算法。

    4.简单实现

    当前的社区项目有redis,简单点实现,例如限制1秒请求1000次,则可以通过redis的incr命令,key则为当前的时间(到秒),计算一秒内的请求次数,当value大于1000时,其余的请求丢弃。

    相关文章

      网友评论

          本文标题:常见限流方案设计与实现

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