ratelimit

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package ratelimit 提供基于键的限流原语:令牌桶 + 滑动窗口两种实现, 外加 HTTP 中间件,可与 pkg/handler 组合(声明式 WithRatelimit)。

设计要点(per-user 限流 + 通用 token bucket):

  • Limiter 接口:Allow(key) (allowed, retryAfter),按 key 隔离(如按 userID / IP);
  • TokenBucket:固定速率补令牌,允许突发;无锁化设计用 sync.Map + 互斥桶;
  • SlidingWindow:滑动窗口(精确),用时间戳 deque;
  • HTTP middleware:超限返回 429 + Retry-After 头;
  • 后台 gc:清理长时间无活动的 key,避免内存泄漏(参考 pkg/token 的 gc 模式)。

零值不可用,用 New 构造。Limiter 并发安全;Stop 后 gc goroutine 退出。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClientIP

func ClientIP(r *http.Request) string

ClientIP 从请求提取客户端 IP(优先 X-Forwarded-For,其次 RemoteAddr)。

func Middleware

func Middleware(l Limiter, keyFn KeyFunc) func(http.Handler) http.Handler

Middleware 返回 HTTP 限流中间件:keyFn 提取 key,limiter 限流。 超限返回 429 + Retry-After 头(秒级)。keyFn 返回空串则跳过限流。

func MiddlewareWithLimiter

func MiddlewareWithLimiter(l Limiter, keyFn KeyFunc) func(http.Handler) http.Handler

MiddlewareWithLimiter 返回带 limiter 注入 ctx 的中间件:下游 handler 可用 FromContext 取 limiter 做更细粒度限流(如对某资源再限一次)。

func WithLimiter

func WithLimiter(ctx context.Context, l Limiter) context.Context

WithLimiter 把 limiter 装入 ctx。供 pkg/handler 的 WithRatelimit 使用。

Types

type KeyFunc

type KeyFunc func(r *http.Request) string

KeyFunc 从请求提取限流 key(如 IP / userID)。返回空串表示不限流(跳过)。

type Limiter

type Limiter interface {
	Allow(key string) (allowed bool, retryAfter time.Duration)
}

Limiter 限流器接口。按 key 隔离(每个 key 独立计数)。 返回 (allowed, retryAfter):retryAfter=0 表示立即可重试或已放行。

func FromContext

func FromContext(ctx context.Context) Limiter

FromContext 从 ctx 取出 Limiter(没有则 nil)。

type Option

type Option func(*config)

Option 配置限流器。

func WithGcInterval

func WithGcInterval(d time.Duration) Option

WithGcInterval 设置 gc 扫描间隔。默认 1min。

func WithMaxIdle

func WithMaxIdle(d time.Duration) Option

WithMaxIdle 设置 key 最大空闲时长(超过则被 gc 回收)。默认 5min。

type SlidingWindow

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

SlidingWindow 滑动窗口限流器:在 window 时长内最多 limit 次请求,精确计数。

func NewSlidingWindow

func NewSlidingWindow(limit int, window time.Duration, opts ...Option) *SlidingWindow

NewSlidingWindow 创建滑动窗口限流器。limit<=0 或 window<=0 视为不限。

func (*SlidingWindow) Allow

func (sw *SlidingWindow) Allow(key string) (bool, time.Duration)

Allow 按 key 限流。滑动窗口:清除早于 window 的旧记录后判断数量。

func (*SlidingWindow) Stop

func (sw *SlidingWindow) Stop()

Stop 停止 gc goroutine。幂等。

func (*SlidingWindow) String

func (sw *SlidingWindow) String() string

type TokenBucket

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

TokenBucket 令牌桶限流器:固定速率补令牌,允许突发(初始满桶)。 burst 为桶容量(最大突发数),rate 为每秒补充令牌数。

func NewTokenBucket

func NewTokenBucket(burst int, rate float64, opts ...Option) *TokenBucket

NewTokenBucket 创建令牌桶限流器。burst<=0 或 rate<=0 视为不限(Allow 永远 true)。 gc 每 gcInterval 清理一次超过 maxIdle 无活动的 key。

func (*TokenBucket) Allow

func (tb *TokenBucket) Allow(key string) (bool, time.Duration)

Allow 按 key 限流。返回是否放行,以及建议的重试等待(超限时)。

func (*TokenBucket) Stop

func (tb *TokenBucket) Stop()

Stop 停止 gc goroutine。幂等。

func (*TokenBucket) String

func (tb *TokenBucket) String() string

String 便于日志/调试。

Jump to

Keyboard shortcuts

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