我想要的:每分鐘
允許n 個請求的限制器。
我嘗試了什么:
(somewhere during init procedure)
limiter = rate.NewLimiter(rate.Every(1*time.Minute/2), 2)
然后在我的 HTTP 服務器的中間件中:
func (self *Router) limiterMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(responseWriter http.ResponseWriter, request *http.Request) {
if !limiter.Allow(){
http.Error(responseWriter, "Too many requests", http.StatusTooManyRequests)
return
}
next.ServeHTTP(responseWriter, request)
})
}
據我了解,這應該允許每分鐘 2 個請求。然后我嘗試發送幾個請求,前兩個請求之間有 15 秒的暫停,然后大約每秒 1 個請求。
期待:
- 前兩個請求有效
- 后續請求獲取 HTTP429 直到 1 分鐘過去,并且第一個后續請求被“清除”
- 另一個請求有效
- 后續請求獲得 HTTP429 直到 15s 已經通過,并且最初的第二個請求被“清除”
實際結果:
22/10/31 14:02:31 access: 200 POST /some/path
22/10/31 14:02:46 access: 200 POST /some/path
22/10/31 14:02:47 access: 429 POST /some/path
22/10/31 14:02:48 access: 429 POST /some/path
22/10/31 14:02:49 access: 429 POST /some/path
22/10/31 14:02:50 access: 429 POST /some/path
22/10/31 14:02:51 access: 429 POST /some/path
22/10/31 14:02:52 access: 429 POST /some/path
22/10/31 14:02:53 access: 429 POST /some/path
22/10/31 14:02:54 access: 429 POST /some/path
22/10/31 14:02:55 access: 429 POST /some/path
22/10/31 14:02:56 access: 429 POST /some/path
22/10/31 14:02:57 access: 429 POST /some/path
22/10/31 14:02:58 access: 429 POST /some/path
22/10/31 14:02:59 access: 429 POST /some/path
22/10/31 14:03:00 access: 429 POST /some/path
22/10/31 14:03:01 access: 200 POST /some/path
22/10/31 14:03:02 access: 429 POST /some/path
22/10/31 14:03:03 access: 429 POST /some/path
22/10/31 14:03:04 access: 429 POST /some/path
22/10/31 14:03:05 access: 429 POST /some/path
22/10/31 14:03:06 access: 429 POST /some/path
22/10/31 14:03:07 access: 429 POST /some/path
22/10/31 14:03:08 access: 429 POST /some/path
22/10/31 14:03:09 access: 429 POST /some/path
22/10/31 14:03:10 access: 429 POST /some/path
22/10/31 14:03:11 access: 429 POST /some/path
22/10/31 14:03:12 access: 429 POST /some/path
22/10/31 14:03:13 access: 429 POST /some/path
22/10/31 14:03:14 access: 429 POST /some/path
22/10/31 14:03:15 access: 429 POST /some/path
22/10/31 14:03:16 access: 429 POST /some/path
22/10/31 14:03:16 access: 429 POST /some/path
22/10/31 14:03:17 access: 429 POST /some/path
22/10/31 14:03:18 access: 429 POST /some/path
22/10/31 14:03:19 access: 429 POST /some/path
22/10/31 14:03:20 access: 429 POST /some/path
22/10/31 14:03:21 access: 429 POST /some/path
22/10/31 14:03:22 access: 429 POST /some/path
22/10/31 14:03:23 access: 429 POST /some/path
22/10/31 14:03:24 access: 429 POST /some/path
22/10/31 14:03:25 access: 429 POST /some/path
22/10/31 14:03:26 access: 429 POST /some/path
22/10/31 14:03:27 access: 429 POST /some/path
22/10/31 14:03:28 access: 429 POST /some/path
22/10/31 14:03:29 access: 429 POST /some/path
22/10/31 14:03:30 access: 429 POST /some/path
22/10/31 14:03:32 access: 200 POST /some/path
22/10/31 14:03:33 access: 429 POST /some/path
從日志中可以看到,在最初的 2 次請求之后,30s 之后發生了第三次成功的請求。這意味著,在 30 秒的正常運行時間內,有 3 個請求成功,而應該只有 2 個。第四個成功的請求在 30 秒后再次發生(總共 60 秒)。
如果我將突發設定為 1,那么最初只有 1 個請求成功,并且每 30 秒再有一個請求可以成功。
所以我不確定我應該如何配置限制器來實作我想要的(每分鐘純n 個請求)。
我究竟做錯了什么?這甚至可以使用內置限制器來實作,還是我需要一個不同的庫來完成這項任務?
uj5u.com熱心網友回復:
Limiter實作了一個令牌桶演算法,本質上是按規定的時間間隔提供令牌。
您在評論中提到了滑動視窗:我不相信用于速率限制的滑動視窗的“標準”實作與您所追求的行為完全匹配。https://konghq.com/blog/how-to-design-a-scalable-rate-limiting-algorithm下描述的方法表明應該使用固定視窗的加權,我已經看到這種方法的實作。也就是說,這仍然不是一個糟糕的方法——像https://github.com/Narasimha1997/ratelimiter這樣的庫可以為你處理這個問題。
您所描述的行為似乎與鏈接文章中描述的“滑動日志”更好地匹配,您可以考慮實施該行為,盡管考慮到它描述的警告。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/524606.html
標籤:去限速
