限流器是服务中非常重要的一个组件,在网关设计、微服务、以及普通的后台应用中都比较常见。它可以限制访问服务的频次和速率,防止服务过载,被刷爆。
限流器的算法比较多,常见的比如令牌桶算法、漏斗算法、信号量等。本文主要介绍基于漏斗算法的一个限流器的实现。文本也提供了其他几种开源的实现方法。
基于令牌桶的限流器实现
在golang 的官方扩展包 time 中(github/go/time),提供了一个基于令牌桶算法的限流器的实现。
原理
令牌桶限流器,有两个概念:
令牌:每次都需要拿到令牌后,才可以访问
桶:有一定大小的桶,桶中最多可以放一定数量的令牌
放入频率:按照一定的频率向通里面放入令牌,但是令牌数量不能超过桶的容量
因此,一个令牌桶的限流器,可以限制一个时间间隔内,最多可以承载桶容量的访问频次。下面我们看看官方的实现。
实现
限流器的定义
下面是对一个限流器的定义:
type Limiter struct {
limit Limit // 放入桶的频率 (Limit 为 float64类型)
burst int // 桶的大小
mu sync.Mutex
tokens float64 // 当前桶内剩余令牌个数
last time.Time // 最近取走token的时间
lastEvent time.Time // 最近限流事件的时间
}
其中,核心参数是 limit,burst。 burst 代表了桶的大小,从实际意义上来讲