一、前言
在高并发场景,为了保证服务高可用,需要实现限流。
如果要控制QPS,简单的做法是维护一个单位时间内的Counter,如判断单位时间已经过去,则将Counter重置零.此做法被认为没有很好的处理单位时间的边界,比如在前一秒的最后一毫秒里和下一秒的第一毫秒都触发了最大的请求数,将目光移动一下,就看到在两毫秒内发生了两倍的QPS.
为了规避上述问题,常用的更平滑的限流算法有漏桶算法和令牌桶算法。
二、漏桶算法(Leaky Bucket)
2.1、漏桶算法的思路
水(请求)先进入到漏桶里,漏桶以一定的速度出水(即接口处理完成),当水流入速度过大会直接溢出(即访问频率超过接口响应速率),然后拒绝请求。
可以看出,漏桶算法能强行限制数据的传输速率。
上面为漏桶算法的示意图。
三、令牌桶算法(token bucket)
令牌桶算法和漏桶算法效果一样,但方向相反的算法,更加容易理解:
随着时间的流逝,系统会按恒定的 1/QPS 时间间隔(如果qps是100,则间隔是10ms)往桶里加入token(想象和漏桶漏水想反,有个水龙头在不断的加水),如果已经满了就不再加了。
每当有新请求来时,会各自拿走一个token,如果token被拿光了,就阻塞会拒绝服务。
令牌桶的另一个好处是,可以方便地改变速度。一旦需要提高速率,则按需提高放入桶中令牌的速率,一般会定时(比如100毫秒)往桶中增加一定数量的令牌。
四、RateLimiter简介
Google的开源工具包guava提供了限流工具类RateLimiter,该类基于令牌桶算法来做限流
更多细节:https://blog.csdn.net/tianyaleixiaowu/article/details/74942405