golang.org/x/time/rate 足够健壮,推荐直接使用;需复用同一实例、避免混用 allown/waitn、burst 不能为0、按ip/用户限流需可信标识、waitn 是主调用方式、rate.limit 单位为事件/秒、它是令牌桶实现。

限流器用 golang.org/x/time/rate 就够了,别自己造轮子
标准库没有限流能力,但官方维护的 rate 包足够健壮、线程安全、内存友好,Go 1.20+ 项目直接用它就行。自己基于 time.Ticker 或 sync.Mutex 实现容易漏掉并发边界或时间漂移问题。
常见错误现象:rate.Limiter 被多个 goroutine 共享时没出错,但误以为要加锁;或者把 Allow() 和 WaitN() 混用导致阻塞逻辑失控。
-
rate.NewLimiter(rate.Limit(10), 1)表示「每秒最多 10 次,初始令牌数为 1」,不是「10 QPS + 1 并发」 -
WaitN(ctx, n)是推荐的主调用方式,它会自动 sleep 到有足够令牌,比AllowN()+ 手动重试更可靠 - 注意
burst参数不能设为 0:设成 0 会导致所有请求立刻被拒,因为初始令牌数为 0 且无法累积
HTTP 中间件里怎么嵌入 rate.Limiter
别在每个 handler 里 new 一个 rate.Limiter,那等于没限流——每个请求都拿到独立的令牌桶。必须复用同一个实例,通常挂到 http.Handler 的字段或全局变量上。
使用场景:API 网关、微服务入口、管理后台接口等需要统一速率控制的地方。
- 按 IP 限流?得自己从
r.RemoteAddr提取真实 IP(注意 X-Forwarded-For 头是否可信),再用sync.Map管理每个 IP 对应的*rate.Limiter - 按用户 ID 限流?确保 ID 来源可信(如 JWT 解析后取
sub字段),避免被伪造绕过 - 不要在
http.HandlerFunc内部调用limiter.WaitN(ctx, 1)后忽略返回 error —— 如果 ctx 超时,WaitN返回context.DeadlineExceeded,必须显式返回 429 或 503
rate.Limit 和 time.Duration 怎么配才不翻车
rate.Limit 类型本质是 float64,单位是「事件/秒」,不是「次/分钟」或「个/毫秒」。写成 rate.Every(100 * time.Millisecond) 看似直观,其实等价于 rate.Limit(10),但隐含了精度损失和可读性陷阱。
性能影响:高 QPS 场景下,rate.Every 会多一次浮点除法,虽然微乎其微,但参数含义不直白,容易传错。
- 想表达「每 200ms 最多 1 次」→ 直接写
rate.Limit(5),别用rate.Every(200 * time.Millisecond) -
rate.Every内部会做1 / d.Seconds()计算,如果传入0或负值,结果是+Inf或-Inf,导致限流器失效 - 测试时用
time.Now().Add(...)模拟时间推进?别碰——rate.Limiter内部用的是time.Now(),mock 需要替换整个 time 包或改用rate.NewLimiterWithClock(Go 1.22+)
漏桶 vs 令牌桶,rate.Limiter 到底是哪个
它是令牌桶(token bucket),不是漏桶(leaky bucket)。区别在于:令牌桶允许突发流量(burst 容量内),漏桶强制匀速输出。Go 的实现支持预充令牌、支持非整数速率、支持阻塞等待,典型令牌桶行为。
容易踩的坑:看到 burst 参数就以为能扛住短时洪峰,但没意识到 burst 只是“缓冲区大小”,不解决后端处理能力瓶颈。比如 burst=100,但下游数据库只能扛 20 QPS,限流器放行后照样雪崩。
- 别把
burst设得远大于平均 QPS:设成 1000 而平均只有 10,等于给攻击者留了放大窗口 - 监控重点不是「被拒绝次数」,而是「平均等待时长」——如果
WaitN平均耗时持续 >100ms,说明令牌生成跟不上消耗,该降级或扩容了 - 不用考虑「动态调整 rate」:运行时修改
limiter.SetLimitAndBurst()是线程安全的,但频繁调用会影响性能,适合按小时/天粒度调整,不适合 per-request 动态策略
事情说清了就结束。真正难的从来不是怎么写限流器,而是判断该在哪一层限、对谁限、限完之后怎么反馈、失败了往哪打日志、指标怎么跟 Prometheus 对齐——这些都没法靠一个 rate.Limiter 自动搞定。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











