Golang限流器rate包源码详细分析

源码地址:golang.org/x/time/rate

rate包是Google基于令牌桶的算法实现的限流器,可以在服务的限流中使用。

一、数据结构

1.常量变量

//定义某个时间的最大频率
//表示每秒的事件数
type Limit float64

//Inf表示无速率限制
const Inf = Limit(math.MaxFloat64)

2. 结构体

Limiter结构体

type Limiter struct {
	limit Limit  //每秒允许处理的事件数量,即每秒处理事件的频率
	burst int   //令牌桶的最大数量, 如果burst为0,则除非limit == Inf,否则不允许处理任何事件。

	mu     sync.Mutex
	tokens float64  //令牌桶中可用的令牌数量
	// last is the last time the limiter's tokens field was updated
	//记录上次limiter的tokens被更新的时间
	last time.Time
	// lastEvent is the latest time of a rate-limited event (past or future)
	//lastEvent记录速率受限制(桶中没有令牌)的时间点,该时间点可能是过去的,也可能是将来的(Reservation预定的结束时间点)
	lastEvent time.Time  
}

Limiter是限流器中最核心的结构体,用于限流(控制事件发生的频率),在初始化后默认是满的,并以每秒r个令牌的速率重新填充直到达到桶的容量(burst),如果r == Inf表示无限制速率。

Limiter有三个主要的方法 Allow、Reserve和Wait,最常用的是Wait和Allow方法

 

这三个方法每调用一次都会消耗一个令牌,这三个方法的区别在于没有令牌时,他们的处理方式不同

Allow: 如果没有令牌,则直接返回false

Reserve:如果没有令牌,则返回一个reservation,

Wait:如果没有令牌,则等待直到获取一个令牌或者其上下文被取消。

 

tokens更新的策略:

1). 成功获取到令牌或成功预约(Reserve)到令牌

2). 预约取消时(Cancel)并且需要还原令牌到令牌桶中时

3). 重新设置限流器的速率时(SetLimit)

4. 重新设置限流器的容量时(SetBurst)

 

lastEvent表示速率受限制的时间点,它可能时过去的时间,也可能时将来的时间。

如果没有预约令牌的话,该时间等于last,是过去的

如果有预约令牌的话,该时间等于最新的预约的截至时间。

 

注意:由于令牌桶的令牌可以预约,所有令牌桶中的tokens可能为负数。

 

Reservation结构体

type Reservation struct {
	ok        bool //到截至时间是否可以获取足够的令牌
	lim       *Limiter
	tokens    int   //需要获取的令牌数量
	timeToAct time.Time  //需要等待的时间点
	// This is the Limit at reservation time, it can change later.
	limit Limit
}

Reservation可以理解成预定令牌的操作,timeToAct是本次预约需要等待到的指定时间点才有足够预约的令牌。

 

二、常用方法

 

1.令牌桶Limiter相关的方法</

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值