使用 golang 服务器对第三方 API 进行速率限制

问题描述 投票:0回答:3

嗨,我有一个带有 gorilla-mux 的 Go 后端,它使用第三方 API。我有一些向此 API 发出请求的处理程序。我的限制是每秒 5 个请求。

我如何实现某种总体速率限制系统,仅在容量可用时(或五个插槽中有一个空闲),请求才会排队并发送?谢谢。

api go limit rate
3个回答
3
投票

对于第 3 方 API 的速率限制请求,您可以使用 Golang 库

golang.org/x/time/rate

使用示例

package main

import (
    "context"
    "log"
    "net/http"
    "time"

    "golang.org/x/time/rate"
)

func main() {
    rl := rate.NewLimiter(rate.Every(10*time.Second), 50)
    reqURL := "https://www.google.com"
    c := http.Client{}

    req, err := http.NewRequest("GET", reqURL, nil)
    if err != nil {
        log.Fatal("failed to create request: %v", err)
    }
    for i := 0; i < 300; i++ {
        // Waiting for rate limiter
        err = rl.Wait(context.Background())
        if err != nil {
            log.Println("failed to wait: %v", err)
        }
        // and doing the requests if the rate is not exceeded
        _, err := c.Do(req)
        if err != nil {
            log.Println("request failed: %v", err)
        }
    }
}

重要!!! 这不是多实例使用的解决方案! 如果您要生成多个服务器,您应该考虑使用 Redis 来同步限制器 (https://github.com/go-redis/redis_rate)。


1
投票

也许你可以尝试这个:https://github.com/dypflying/leakybucket,假设漏桶算法速率限制器可能适合你的场景。


0
投票

如果我理解得很好,您有一个应用程序 X 应该连接到 API Y,并且 X 每秒不能向 Y 发送超过 5 个请求。

这是一个复杂且不完整的场景。请教几个问题

  1. X 上的预期负载是多少?如果每秒请求数低于 5 个……就可以了
  2. X 的超时时间是多少?想象一下,您每秒收到 50 个请求……在这种情况下,您可能需要 10 秒来回答某些请求,可以吗?
  3. X超时的情况下,客户端会重试吗?
  4. 如果每秒调用 Y 的请求超过 5 个,会发生什么?
  5. Y 的响应是否可缓存
  6. 您有多个服务器/自动缩放吗?

一种可能性是在应用程序上设置速率限制器以匹配 API 上的限制。

另一个就是尽可能多地调用API。如果由于请求太多而失败,您可以实现重试逻辑或放弃。

如果您出于某种原因需要非常小心地使用此 API,并且不需要运行多个实例/自动缩放,解决方案是在应用程序上使用速率限制器。

如果您需要运行多个实例,您需要集中对此 API 的访问,这是一件非常微妙的事情……它是单点故障。您可以实现一个每秒仅交付 5 个令牌的令牌系统。获得令牌后,您就可以访问 API。这是一种可能性。

天下没有免费的午餐。每个解决方案都有优点和缺点。但是,如果您可以避免对 API 执行请求(例如缓存结果),或者如果您只需要存储数据(并运行异步程序),则可以将消息添加到队列中……也许会更容易讨论更好的解决方案

© www.soinside.com 2019 - 2024. All rights reserved.