登录
首页 >  Golang >  Go问答

每分钟限制 N 个请求使用 golang.org/x/time/rate

来源:stackoverflow

时间:2024-02-08 12:51:24 154浏览 收藏

“纵有疾风来,人生不言弃”,这句话送给正在学习Golang的朋友们,也希望在阅读本文《每分钟限制 N 个请求使用 golang.org/x/time/rate》后,能够真的帮助到大家。我也会在后续的文章中,陆续更新Golang相关的技术文章,有好的建议欢迎大家在评论留言,非常感谢!

问题内容

我想要什么:

每分钟允许 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,直到 15 秒已通过,并且最初的第二个请求被“清除”

实际结果:

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 个请求)。

我做错了什么?这甚至可以使用内置限制器来实现,还是我需要一个不同的库来完成此任务?


正确答案


Limiter实现了令牌桶算法,本质上是按照规定的时间间隔喂令牌。

您在评论中提到了滑动窗口:我不相信用于速率限制的滑动窗口的“标准”实现将与您所追求的行为完全匹配。 https://konghq.com/blog/how-to-design-a-scalable-rate-limiting-algorithm 中描述的方法表明应使用固定窗口的加权,并且我已经看到这种类型的方法已实现。也就是说,这仍然是一个不错的方法 - 像 https://github.com/Narasimha1997/ratelimiter 这样的库可以为您处理这个问题。

您所描述的行为似乎更符合链接文章中所描述的“滑动日志”,您可以考虑实现该行为,尽管它描述了一些注意事项。

今天关于《每分钟限制 N 个请求使用 golang.org/x/time/rate》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>