Go 多租户限流中的公平性设计

问题不是“限流”,而是“谁被限” 多租户系统里,单一全局令牌桶会让大租户挤压小租户,最终演变成“有流量的客户拿走全部容量”。 分层限流模型 全局桶:保护系统总容量。 租户桶:保证最小公平份额。 接口桶:关键路径优先级保护。 动态配额 基础配额按套餐或 SLA 分层。 空闲配额可借用,但需可回收。 通过窗口统计识别恶意突刺流量。 小结 限流策略是否成功,不看是否拦截,而看是否在拥塞时仍然维持“可预期的租户体验”。

2026年5月21日 · 1 分钟 · BvBeJ

Go 服务限流:用令牌桶保护你的 API

背景 服务刚上线时,大家最担心的是没流量。等真有流量了,新的问题马上出现: 某个接口被脚本打爆 下游数据库扛不住瞬时峰值 重试风暴把正常请求一起拖死 这时候如果没有限流,服务再快也会被拖垮。 Go 很适合写高并发服务,限流逻辑做成中间件也很自然。今天聊一个最常见、也最实用的方案:令牌桶。 为什么是令牌桶 令牌桶的规则很简单: 系统按固定速率往桶里放令牌 请求到来时先拿一个令牌 拿到就放行,拿不到就拒绝或排队 它的好处是同时兼顾两件事: 控制平均速率 允许短时间突发 比如接口平时稳定在每秒 100 个请求,但偶尔瞬间冲到 150,只要桶里有积累的令牌,就不一定要马上拒绝。 单机场景:HTTP 中间件 Go 官方扩展库里已经有现成实现:golang.org/x/time/rate。 package main import ( "net/http" "time" "golang.org/x/time/rate" ) func RateLimitMiddleware(limiter *rate.Limiter, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if !limiter.Allow() { w.WriteHeader(http.StatusTooManyRequests) _, _ = w.Write([]byte("rate limit exceeded")) return } next.ServeHTTP(w, r) }) } func main() { mux := http.NewServeMux() mux.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("ok")) }) limiter := rate.NewLimiter(rate.Every(10*time.Millisecond), 20) server := &http.Server{ Addr: ":8080", Handler: RateLimitMiddleware(limiter, mux), } _ = server.ListenAndServe() } 这段配置的含义: ...

2026年4月14日 · 2 分钟 · BvBeJ