Documentation
¶
Overview ¶
Package rate provides a rate limiter.
package rate 提供基于Redis的分布式令牌桶限流器实现 支持配置令牌生成速率、桶容量、过期时间及分布式开关,兼容Redis 6.0+
Index ¶
- Constants
- type Limit
- type Limiter
- func (lim *Limiter) Allow() bool
- func (lim *Limiter) AllowN(now time.Time, n int) bool
- func (lim *Limiter) Burst() int
- func (lim *Limiter) Limit() Limit
- func (lim *Limiter) Reserve() *Reservation
- func (lim *Limiter) ReserveN(now time.Time, n int) *Reservation
- func (lim *Limiter) SetLimit(newLimit Limit)
- func (lim *Limiter) SetLimitAt(now time.Time, newLimit Limit)
- func (lim *Limiter) Wait(ctx context.Context) (err error)
- func (lim *Limiter) WaitN(ctx context.Context, n int) (err error)
- type LocalRateLimiter
- type Option
- type RateLimitStats
- type RateLimiter
- type RedisRateLimiter
- func (r *RedisRateLimiter) Allow(resource string) bool
- func (r *RedisRateLimiter) AllowN(resource string, tokens int64) bool
- func (r *RedisRateLimiter) Close() error
- func (r *RedisRateLimiter) GetConfig() (bucket int, limit float64, expire int)
- func (r *RedisRateLimiter) GetRemaining(resource string) (float64, error)
- func (r *RedisRateLimiter) GetStats() (allowed, denied, fastDenied int64, lastReset time.Time)
- func (r *RedisRateLimiter) ResetStats()
- type Reservation
Constants ¶
const Inf = Limit(math.MaxFloat64)
Inf is the infinite rate limit; it allows all events (even if burst is zero).
const InfDuration = time.Duration(1<<63 - 1)
InfDuration is the duration returned by Delay when a Reservation is not OK.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Limit ¶
type Limit float64
Limit defines the maximum frequency of some events. Limit is represented as number of events per second. A zero Limit allows no events.
type Limiter ¶
type Limiter struct {
// contains filtered or unexported fields
}
A Limiter controls how frequently events are allowed to happen. It implements a "token bucket" of size b, initially full and refilled at rate r tokens per second. Informally, in any large enough time interval, the Limiter limits the rate to r tokens per second, with a maximum burst size of b events. As a special case, if r == Inf (the infinite rate), b is ignored. See https://en.wikipedia.org/wiki/Token_bucket for more about token buckets.
The zero value is a valid Limiter, but it will reject all events. Use NewLimiter to create non-zero Limiters.
Limiter has three main methods, Allow, Reserve, and Wait. Most callers should use Wait.
Each of the three methods consumes a single token. They differ in their behavior when no token is available. If no token is available, Allow returns false. If no token is available, Reserve returns a reservation for a future token and the amount of time the caller must wait before using it. If no token is available, Wait blocks until one can be obtained or its associated context.Context is canceled.
The methods AllowN, ReserveN, and WaitN consume n tokens.
func NewLimiter ¶
NewLimiter returns a new Limiter that allows events up to rate r and permits bursts of at most b tokens.
func (*Limiter) AllowN ¶
AllowN reports whether n events may happen at time now. Use this method if you intend to drop / skip events that exceed the rate limit. Otherwise use Reserve or Wait.
func (*Limiter) Burst ¶
Burst returns the maximum burst size. Burst is the maximum number of tokens that can be consumed in a single call to Allow, Reserve, or Wait, so higher Burst values allow more events to happen at once. A zero Burst allows no events, unless limit == Inf.
func (*Limiter) Reserve ¶
func (lim *Limiter) Reserve() *Reservation
Reserve is shorthand for ReserveN(time.Now(), 1).
func (*Limiter) ReserveN ¶
func (lim *Limiter) ReserveN(now time.Time, n int) *Reservation
ReserveN returns a Reservation that indicates how long the caller must wait before n events happen. The Limiter takes this Reservation into account when allowing future events. ReserveN returns false if n exceeds the Limiter's burst size. Usage example:
r := lim.ReserveN(time.Now(), 1)
if !r.OK() {
// Not allowed to act! Did you remember to set lim.burst to be > 0 ?
return
}
time.Sleep(r.Delay())
Act()
Use this method if you wish to wait and slow down in accordance with the rate limit without dropping events. If you need to respect a deadline or cancel the delay, use Wait instead. To drop or skip events exceeding rate limit, use Allow instead.
func (*Limiter) SetLimitAt ¶
SetLimitAt sets a new Limit for the limiter. The new Limit, and Burst, may be violated or underutilized by those which reserved (using Reserve or Wait) but did not yet act before SetLimitAt was called.
type LocalRateLimiter ¶
type LocalRateLimiter struct {
// contains filtered or unexported fields
}
func (*LocalRateLimiter) Allow ¶
func (self *LocalRateLimiter) Allow(resource string) bool
type Option ¶
Option 限流器配置选项 字段含义:
Limit: 令牌生成速率(每秒生成的令牌数,支持小数,如0.5表示每2秒生成1个) Bucket: 令牌桶容量(最大可存放的令牌数,必须>0) Expire: Redis键过期时间(毫秒,<=0时使用默认5分钟) Distributed: 是否启用分布式模式(当前实现基于Redis,必须设为true,否则返回错误)
type RateLimitStats ¶ added in v1.1.0
type RateLimitStats struct {
AllowedRequests int64 // 允许的请求数
DeniedRequests int64 // 拒绝的请求数
FastDenied int64 // 快速拒绝的请求数(请求令牌数超桶容量)
LastReset time.Time // 上次重置时间
}
RateLimitStats 限流统计信息
type RateLimiter ¶
func NewRateLimiter ¶
func NewRateLimiter(option Option) RateLimiter
type RedisRateLimiter ¶
type RedisRateLimiter struct {
// contains filtered or unexported fields
}
RedisRateLimiter 基于Redis的分布式令牌桶限流器
func NewRedisRateLimiter ¶ added in v1.1.0
func NewRedisRateLimiter(option Option) (*RedisRateLimiter, error)
NewRedisRateLimiter 创建限流器实例 注意:Distributed必须为true(当前实现仅支持分布式模式)
func (*RedisRateLimiter) Allow ¶
func (r *RedisRateLimiter) Allow(resource string) bool
Allow 判断当前请求是否允许通过(消耗1个令牌) resource:需要限流的资源标识(如API路径、用户ID等) 返回true表示允许,false表示被限流
func (*RedisRateLimiter) AllowN ¶ added in v1.1.0
func (r *RedisRateLimiter) AllowN(resource string, tokens int64) bool
AllowN 判断是否允许通过并消耗N个令牌 扩展方法:支持消耗多个令牌的场景
func (*RedisRateLimiter) Close ¶ added in v1.1.0
func (r *RedisRateLimiter) Close() error
Close 关闭限流器,释放资源
func (*RedisRateLimiter) GetConfig ¶ added in v1.1.0
func (r *RedisRateLimiter) GetConfig() (bucket int, limit float64, expire int)
GetConfig 获取当前限流器配置
func (*RedisRateLimiter) GetRemaining ¶ added in v1.1.0
func (r *RedisRateLimiter) GetRemaining(resource string) (float64, error)
GetRemaining 获取指定资源的剩余令牌数(近似值) 注意:由于分布式环境,返回的是查询时刻的近似值
func (*RedisRateLimiter) GetStats ¶ added in v1.1.0
func (r *RedisRateLimiter) GetStats() (allowed, denied, fastDenied int64, lastReset time.Time)
GetStats 获取当前限流统计信息(线程安全)
func (*RedisRateLimiter) ResetStats ¶ added in v1.1.0
func (r *RedisRateLimiter) ResetStats()
ResetStats 重置统计计数器(线程安全)
type Reservation ¶
type Reservation struct {
// contains filtered or unexported fields
}
A Reservation holds information about events that are permitted by a Limiter to happen after a delay. A Reservation may be canceled, which may enable the Limiter to permit additional events.
func (*Reservation) Cancel ¶
func (r *Reservation) Cancel()
Cancel is shorthand for CancelAt(time.Now()).
func (*Reservation) CancelAt ¶
func (r *Reservation) CancelAt(now time.Time)
CancelAt indicates that the reservation holder will not perform the reserved action and reverses the effects of this Reservation on the rate limit as much as possible, considering that other reservations may have already been made.
func (*Reservation) Delay ¶
func (r *Reservation) Delay() time.Duration
Delay is shorthand for DelayFrom(time.Now()).
func (*Reservation) DelayFrom ¶
func (r *Reservation) DelayFrom(now time.Time) time.Duration
DelayFrom returns the duration for which the reservation holder must wait before taking the reserved action. Zero duration means act immediately. InfDuration means the limiter cannot grant the tokens requested in this Reservation within the maximum wait time.
func (*Reservation) OK ¶
func (r *Reservation) OK() bool
OK returns whether the limiter can provide the requested number of tokens within the maximum wait time. If OK is false, Delay returns InfDuration, and Cancel does nothing.