Golang的滑動視窗計數器Redis限速實現

banq發表於2021-11-23

這是一個基於Figma 工程團隊的部落格文章構建的簡單速率限制器。
有關實際演算法的要求和設計的資訊,請參閱帖子。
限速器滿足這個介面:

type  Limiter  interface {
     Increment (context. Context , string , int ) error 
}

該實現由 Redis 支援並使用 go-redis 庫。

client := goredis.NewClient(&goredis.Options{
    Addr: "localhost:6379",
})

ratelimiter := redis.New(client, 10, time.Minute, time.Hour)

ratelimiter.Increment(ctx, "user_id", 1)

為方便起見,還有一個 http 中介軟體。靈感來自 Seth Vargo 的速率限制庫:

ratelimiter := redis.New(client, 10, time.Minute, time.Hour)
mw := ratelimit.Middleware(ratelimiter, ratelimit.IPKeyFunc, 1)
// use mw in your favourite HTTP library


Middleware函式有一個weight引數,它允許您為某些路由提供更高的增量權重。例如,您的基本速率限制可以是每小時 1000 個請求,每個請求的權重為 1,但計算量特別大的端點可能希望權重為 10,因此每個請求將內部計數器增加 10 而不是 1 .
如果您使用多箇中介軟體例項,請確保不要向全域性多路複用器/路由器新增一個,否則您的請求將觸發兩個速率限制計算(因此,Redis 網路 I/O 操作)。這可以在未來透過集中式中介軟體控制器來解決,該控制器提供具有優先順序規則順序等的限制器樹。
原始碼檢視 Github

相關文章