限流:计数器、漏桶、令牌桶 三大算法的原理与实战(史上最全)

限流:计数器、漏桶、令牌桶 三大算法的原理与实战(史上最全)

令牌桶算法原理及实现(图文详解) https://mikechen.cc/20379.html

Redis 实现限流的三种方式  https://juejin.cn/post/7033646189845151757

 

 

限流算法很多,常见的有三类,分别是计数器算法、漏桶算法、令牌桶算法,下面逐一讲解。

限流的手段通常有计数器、漏桶、令牌桶。注意限流和限速(所有请求都会处理)的差别,视
业务场景而定。

(1)计数器

  • 在一段时间间隔内(时间窗/时间区间),处理请求的最大数量固定,超过部分不做处理。
    • 简单粗暴,比如指定线程池大小,指定数据库连接池大小、nginx连接数等,这都属于计数器算法。
    • 比如我们规定对于A接口,我们1分钟的访问次数不能超过100个。
      • 在一开 始的时候,我们可以设置一个计数器counter,每当一个请求过来的时候,counter就加1,如果counter的值大于100并且该请求与第一个请求的间隔时间还在1分钟之内,那么说明请求数过多,拒绝访问;
      • 如果该请求与第一个请求的间隔时间大于1分钟,且counter的值还在限流范围内,那么就重置 counter,就是这么简单粗暴。 

这个算法虽然简单,但是有一个十分致命的问题,那就是临界问题,我们看下图:

img

从上图中我们可以看到,假设有一个恶意用户,他在0:59时,瞬间发送了100个请求,并且1:00又瞬间发送了100个请求,那么其实这个用户在 1秒里面,瞬间发送了200个请求。

我们刚才规定的是1分钟最多100个请求(规划的吞吐量),也就是每秒钟最多1.7个请求,用户通过在时间窗口的重置节点突发请求, 可以瞬间超过我们的速率限制。

用户有可能通过算法的这个漏洞,瞬间压垮我们的应用。

 

(2)漏桶:

  • 漏桶大小固定,处理速度固定,但请求进入速度不固定(在突发情况请求过多时,会丢弃过多的请求)。
  • 原理 简单理解:水(请求)先进入到漏桶里,漏桶一定的速度出水,当水流入速度过大会超过桶可接纳的容量时直接溢出

问题:漏桶出口的速度固定不能灵活的应对后端能力提升。比如,通过动态扩容,后端流量从1000QPS提升到1WQPS,漏桶没有办法。

 

(3)令牌桶:

令牌桶的大小固定,令牌的产生速度固定,但是消耗令牌(即请求)速度不固定(可以应对一些某些时间请求过多的情况);每个请求都会从令牌桶中取出令牌,如果没有令牌则丢弃该次请求。

 

 好处:

令牌桶的好处之一就是可以方便地应对 突发出口流量后端能力的提升)。

比如,可以改变令牌的发放速度,算法能按照新的发送速率调大令牌的发放数量,使得出口突发流量能被处理。

 

posted on 2024-01-12 18:18  gogoy  阅读(38)  评论(0编辑  收藏  举报

导航