【问题标题】:Rate limit function 40/second with "golang.org/x/time/rate"使用“golang.org/x/time/rate”的速率限制函数 40/秒
【发布时间】:2019-02-27 07:25:23
【问题描述】:

我正在尝试使用“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)
    }
}

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

RateLimitFunc()

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

【问题讨论】:

    标签: go


    【解决方案1】:

    在此处阅读文档; link

    您可以看到NewLimiter 的第一个参数是rate.Limit 类型。

    如果您希望每秒 40 个请求,那么这意味着每 25 毫秒 1 个请求的速率。

    您可以通过以下方式创建它:

    limiter := rate.NewLimiter(rate.Every(25 * time.Millisecond), 2)
    

    旁注:

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

    【讨论】:

    • 只是想指出,将其写为rate.Every(time.Second / 40) 可能比先将 40 req/sec 转换为 ms/req 更直观和可读。
    • 文档已经将Limit定义为每秒事件数 - 那么为什么不简单地使用rate.Limit(40)呢?
    • 基于意见:我建议rate.Limit(40) 可能是可能的,但如果不阅读文档,也可能会误解这一点,因为限制器总共限制为 40 个请求。
    • 我的评论是基于意见的..不是文档或响应。
    • Re“In generate”:你的意思是“In general”吗?
    【解决方案2】:
    func RateLimit(ctx context.Context) {
        limiter := rate.NewLimiter(40, 10)
        err := limiter.Wait(ctx)
        if err != nil {
            // Log the error and return
        }
        // Do the actual work here
    }
    

    作为 Zak said,不要根据 Go 文档 context 将 Context 存储在结构类型中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-01
      • 1970-01-01
      • 2010-09-12
      相关资源
      最近更新 更多