Golang📌常用包📌x-time-rate.txt
"golang.org/x/time/rate"包实现了一个基于令牌桶算法的限流器,用于控制事件发生的频率。

========== ========== ========== ========== ==========

type Limit float64
定义最大事件频率(事件数/秒),0不允许任何事件,Inf允许任何事件(不限)。

func Every(interval time.Duration) Limit
将最小时间间隔转成频率

func NewLimiter(r Limit, b int) *Limiter
返回一个指定频率和最大允许突发流量的限流器
var highLimiter = rate.NewLimiter(10, 5)
var lowLimiter = rate.NewLimiter(rate.Every(30*time.Second), 2)

func (lim *Limiter) Limit() Limit
func (lim *Limiter) Burst() int
func (lim *Limiter) Tokens() float64
func (lim *Limiter) TokensAt(t time.Time) float64
状态查询

func (lim *Limiter) SetLimit(newLimit Limit)
func (lim *Limiter) SetLimitAt(t time.Time, newLimit Limit)
func (lim *Limiter) SetBurst(newBurst int)
func (lim *Limiter) SetBurstAt(t time.Time, newBurst int)
动态调整

func (lim *Limiter) Allow() bool
func (lim *Limiter) AllowN(t time.Time, n int) bool
是否可执行事件

func (lim *Limiter) Wait(ctx context.Context) (err error)
func (lim *Limiter) WaitN(ctx context.Context, n int) (err error)
阻塞直到获取令牌或上下文被取消

func (lim *Limiter) Reserve() *Reservation
func (lim *Limiter) ReserveN(t time.Time, n int) *Reservation
预约令牌

func (r *Reservation) OK() bool
预约是否有效

func (r *Reservation) Delay() time.Duration
func (r *Reservation) DelayFrom(t time.Time) time.Duration
返回需要等待的时间

func (r *Reservation) Cancel()
func (r *Reservation) CancelAt(t time.Time)
取消预约

========== ========== ========== ========== ==========

var limiter = rate.NewLimiter(1, 1)

func doOrSkip() {
	if !limiter.Allow() {
		return // 当前拿不到令牌直接返回
	}
	log.Println("doOrSkip")
}

func waitToDo(ctx context.Context) {
	if err := limiter.Wait(ctx); err != nil {
		return // 超时未拿到令牌则返回
	}
	log.Println("waitToDo")
}