什么是限流
在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。限流可以认为服务降级的一种,限流通过限制请求的流量以达到保护系统的目的。
固定窗口限流算法
内部维护一个计数器,将单位时间段当做一个窗口,计数器记录这个窗口接收请求的次数。如果单位时间请求没有到达阈值,则计数器加1,正常请求;如果到达阈值,则访问拒绝;在开启下一个单位时间窗口时,计数器清0。
固定窗口限流实现较为简单,但是也存在一个问题,就是它无法解决临界问题。假设我们的限流时10次/秒,在0.8s-1s之前请求5次,在1s-1.2s请求五次,按照固定窗口限流算法,他们在单位时间都没有达到阈值,但是在0.8s-1.2s的时候其实已经达到了限流的阈值。
滑动窗口限流算法
滑动窗口时为了解决固定窗口限流的缺陷,将单位限流时间再细分为n小的窗口,然后每次统计每个小周期内的访问次数,小窗口划分的越细,则系统越平滑。
漏桶算法
漏桶算法面对限流,就更加的柔性,不存在直接的粗暴拒绝。
它的原理很简单,可以认为就是注水漏水的过程。往漏桶中以任意速率流入水,以固定的速率流出水。当水超过桶的容量时,会被溢出,也就是被丢弃。因为桶容量是不变的,保证了整体的速率。
在正常流量的时候,系统按照固定的速率处理请求,是我们想要的。但是面对突发流量的时候,漏桶算法还是循规蹈矩地处理请求,这就不是我们想看到的啦。流量变突发时,我们肯定希望系统尽量快点处理请求,提升用户体验嘛。
令牌桶算法
面对突发流量的时候,我们可以使用令牌桶算法限流。
有一个令牌管理员,根据限流大小,定速往令牌桶里放令牌。
如果令牌数量满了,超过令牌桶容量的限制,那就丢弃。
系统在接受到一个用户请求时,都会先去令牌桶要一个令牌。如果拿到令牌,那么就处理这个请求的业务逻辑;
如果拿不到令牌,就直接拒绝这个请求。
如果令牌发放的策略正确,这个系统即不会被拖垮,也能提高机器的利用率。Guava的RateLimiter限流组件,就是基于令牌桶算法实现的。