速率限制功能 40/second with "golang.org/x/time/rate"

bud*_*dge 5 go

我正在尝试使用“golang.org/x/time/rate”来构建一个函数,该函数在令牌可用之前一直阻塞。这是使用库将代码块速率限制为每秒 40 个请求,存储桶大小为 2 的正确方法吗?

type Client struct {
    limiter        *rate.Limiter
    ctx context.Context
}

func NewClient() *Client {
    c :=Client{}
    c.limiter = rate.NewLimiter(40, 2)
    c.ctx = context.Background()
    return &c
}

func (client *Client) RateLimitFunc() {

    err := client.limiter.Wait(client.ctx)
    if err != nil {
        fmt.Printf("rate limit error: %v", err)
    }
}
Run Code Online (Sandbox Code Playgroud)

对我调用的代码块进行速率限制

RateLimitFunc()
Run Code Online (Sandbox Code Playgroud)

我不想使用自动收报机,因为我希望速率限制器考虑调用代码运行的时间长度。

Zak*_*Zak 8

在这里阅读文档;关联

您可以看到第一个参数 toNewLimiter的类型为rate.Limit

如果您想要 40 个请求/秒,那么这转化为每 25 毫秒 1 个请求的速率。

您可以通过执行以下操作来创建它:

limiter := rate.NewLimiter(rate.Every(25 * time.Millisecond), 2)
Run Code Online (Sandbox Code Playgroud)

边注:

  • 在生成上下文中ctx不应存储在结构中,而应按请求进行。看起来Client会被重用,因此您可以将上下文传递给RateLimitFunc()或 任何合适的地方,而不是在客户端结构上存储单个上下文。

  • 只是想指出,将其写为“rate.Every(time.Second / 40)”而不是先将 40 req/sec 转换为 ms/req 可能更直观和可读。 (7认同)
  • 文档已经定义了 [Limit](https://godoc.org/golang.org/x/time/rate#Limit) _作为每秒事件数_ - 那么为什么不简单地定义 `rate.Limit(40)` 呢? (3认同)