Help us shape the future of Go! Take the 2026 Go Developer Survey

ratelimit

package
v0.5.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package ratelimit 提供通用限流器实现。

支持令牌桶和滑动窗口两种限流算法,以及按 key 隔离的限流器管理。

用法:

// 令牌桶限流器
limiter := ratelimit.NewTokenBucket(100, 200) // 100 QPS, burst 200
if limiter.Allow() {
    // 处理请求
}

// 按 key 隔离的限流器(如按用户 ID)
keyed := ratelimit.NewKeyedLimiter(func() ratelimit.Limiter {
    return ratelimit.NewTokenBucket(10, 20)
}, 10*time.Minute)
if keyed.Allow("user:123") {
    // 处理请求
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type KeyedLimiter

type KeyedLimiter = KeyedLimiterOf[string]

KeyedLimiter 是 string key 的别名,兼容既有调用方。

func NewKeyedLimiter

func NewKeyedLimiter(factory func() Limiter, ttl time.Duration) *KeyedLimiter

NewKeyedLimiter 创建 string key 的限流器管理器(兼容旧 API)。

参数:

  • factory: 创建新限流器的工厂函数
  • ttl: 限流器空闲过期时间,超过此时间未使用的限流器会被清理

用法:

keyed := ratelimit.NewKeyedLimiter(func() ratelimit.Limiter {
    return ratelimit.NewTokenBucket(10, 20)
}, 10*time.Minute)

type KeyedLimiterOf added in v0.5.0

type KeyedLimiterOf[K comparable] struct {
	// contains filtered or unexported fields
}

KeyedLimiterOf 是按 key 隔离的限流器管理器(key 类型可定制)。 每个 key 维护独立的限流器实例,支持空闲回收、容量护栏、速率热更。

func NewKeyedLimiterOf added in v0.5.0

func NewKeyedLimiterOf[K comparable](factory func() Limiter, opts ...KeyedOption[K]) *KeyedLimiterOf[K]

NewKeyedLimiterOf 创建按 key 隔离的限流器管理器(key 任意 comparable 类型)。

用法:

keyed := ratelimit.NewKeyedLimiterOf[uint](
    func() ratelimit.Limiter { return ratelimit.NewTokenBucket(10, 20) },
    ratelimit.WithIdleTTL[uint](10*time.Minute),
    ratelimit.WithMaxEntries[uint](10_000),
)

func (*KeyedLimiterOf[K]) Allow added in v0.5.0

func (kl *KeyedLimiterOf[K]) Allow(key K) bool

Allow 检查指定 key 是否允许请求。容量护栏拒绝未登记 key 时返回 false。

func (*KeyedLimiterOf[K]) AllowN added in v0.5.0

func (kl *KeyedLimiterOf[K]) AllowN(key K, n int) bool

AllowN 检查指定 key 是否允许 N 个请求。容量护栏拒绝未登记 key 时返回 false。

func (*KeyedLimiterOf[K]) AllowWithRetryAfter added in v0.5.0

func (kl *KeyedLimiterOf[K]) AllowWithRetryAfter(key K) (wait time.Duration, ok bool)

AllowWithRetryAfter 检查是否放行;拒绝时返回建议等待时长(不消耗令牌的探测)。

  • ok=true:请求放行,wait=0
  • ok=false:请求拒绝;wait 是下一个可用令牌的等待时长(Reserve→Delay→Cancel, 不消耗令牌),容量护栏拒绝时返回建议 Retry-After

探测语义:被拒请求不会自我消耗配额,避免放大限流(429 + Retry-After 场景)。

func (*KeyedLimiterOf[K]) Close added in v0.5.0

func (kl *KeyedLimiterOf[K]) Close()

Close 关闭限流器管理器,停止清理 goroutine。可安全重复调用。

func (*KeyedLimiterOf[K]) Delete added in v0.5.0

func (kl *KeyedLimiterOf[K]) Delete(key K)

Delete 删除指定 key 的限流器。

func (*KeyedLimiterOf[K]) Get added in v0.5.0

func (kl *KeyedLimiterOf[K]) Get(key K) Limiter

Get 获取指定 key 的限流器。表满且 key 未登记时返回 nil。

func (*KeyedLimiterOf[K]) Len added in v0.5.0

func (kl *KeyedLimiterOf[K]) Len() int

Len 返回当前活跃的限流器数量。

func (*KeyedLimiterOf[K]) OverCapHits added in v0.5.0

func (kl *KeyedLimiterOf[K]) OverCapHits() int64

OverCapHits 返回容量护栏拒绝未登记 key 的累计次数(可观测性)。

func (*KeyedLimiterOf[K]) Replace added in v0.5.0

func (kl *KeyedLimiterOf[K]) Replace(key K, l Limiter)

Replace 将指定 key 的限流器替换为新实例(速率热更)。 换桶即新配额,桶内余量归零(调用方接受)。key 不存在时等价登记新桶。

type KeyedOption added in v0.5.0

type KeyedOption[K comparable] func(*keyedConfig[K])

KeyedOption 是 KeyedLimiterOf 的函数选项。

func WithIdleTTL added in v0.5.0

func WithIdleTTL[K comparable](ttl time.Duration) KeyedOption[K]

WithIdleTTL 设置空闲回收周期;表满时也先触发回收再判满。 <=0 使用默认 1 分钟。

func WithMaxEntries added in v0.5.0

func WithMaxEntries[K comparable](max int) KeyedOption[K]

WithMaxEntries 设置容量护栏上限(未登记 key 在表满时被拒绝,已登记 key 不受影响)。 0 = 不限(默认)。

func WithOverCapRetryAfter added in v0.5.0

func WithOverCapRetryAfter[K comparable](d time.Duration) KeyedOption[K]

WithOverCapRetryAfter 设置容量护栏拒绝时 AllowWithRetryAfter 返回的建议等待。 <=0 使用默认 1 分钟。

type Limiter

type Limiter interface {
	// Allow 检查是否允许一个请求。
	Allow() bool

	// AllowN 检查是否允许 N 个请求。
	AllowN(n int) bool

	// Reserve 预留一个令牌,返回需要等待的时间。
	// 如果返回 0 表示立即可用。
	Reserve() time.Duration
}

Limiter 是通用限流器接口。

type SlidingWindow

type SlidingWindow struct {
	// contains filtered or unexported fields
}

SlidingWindow 是滑动窗口限流器。 在指定时间窗口内限制请求次数。

func NewSlidingWindow

func NewSlidingWindow(window time.Duration, maxCount int) *SlidingWindow

NewSlidingWindow 创建滑动窗口限流器。

参数:

  • window: 时间窗口大小
  • maxCount: 窗口内最大请求数

用法:

limiter := ratelimit.NewSlidingWindow(time.Minute, 100) // 每分钟最多 100 次

func (*SlidingWindow) Allow

func (sw *SlidingWindow) Allow() bool

Allow 检查是否允许一个请求。

func (*SlidingWindow) AllowN

func (sw *SlidingWindow) AllowN(n int) bool

AllowN 检查是否允许 N 个请求。n<=0 视为 0 个请求,直接放行(不占槽位)。

func (*SlidingWindow) Count

func (sw *SlidingWindow) Count() int

Count 返回当前窗口内的请求数。

func (*SlidingWindow) Reserve

func (sw *SlidingWindow) Reserve() time.Duration

Reserve 预留一个请求,返回需要等待的时间。 返回 0 表示立即放行(槽位已计入窗口);返回 d>0 表示需等待 d 后放行, 槽位已按 now+d 预占——与 x/time/rate 的 Reserve 语义一致:预留即消费, 并发调用者拿到的是互不相同的槽位而非同一个"虚拟许可"。

func (*SlidingWindow) Reset

func (sw *SlidingWindow) Reset()

Reset 重置限流器。

type TokenBucket

type TokenBucket struct {
	// contains filtered or unexported fields
}

TokenBucket 是令牌桶限流器。 基于 golang.org/x/time/rate 实现,支持平滑限流。

func NewTokenBucket

func NewTokenBucket(rps rate.Limit, burst int) *TokenBucket

NewTokenBucket 创建令牌桶限流器。

参数:

  • rps: 每秒允许的请求数(Requests Per Second)
  • burst: 突发容量(令牌桶最大容量)

用法:

limiter := ratelimit.NewTokenBucket(100, 200) // 100 QPS, burst 200

func (*TokenBucket) Allow

func (tb *TokenBucket) Allow() bool

Allow 检查是否允许一个请求。

func (*TokenBucket) AllowN

func (tb *TokenBucket) AllowN(n int) bool

AllowN 检查是否允许 N 个请求。

func (*TokenBucket) Burst

func (tb *TokenBucket) Burst() int

Burst 返回限流器的 burst 配置。

func (*TokenBucket) Rate

func (tb *TokenBucket) Rate() rate.Limit

Rate 返回限流器的 RPS 配置。

func (*TokenBucket) Reserve

func (tb *TokenBucket) Reserve() time.Duration

Reserve 预留一个令牌,返回需要等待的时间。

func (*TokenBucket) RetryAfter added in v0.5.0

func (tb *TokenBucket) RetryAfter() (time.Duration, bool)

RetryAfter 探测下一个可用令牌的等待时长,不消耗令牌(Reserve→Delay→Cancel)。 ok=false 表示限流器本身不可用(如 burst=0 且 rps=0)。 被拒请求不会自我消耗配额——429 + Retry-After 场景的标准姿势。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL