如何设计 goroutines 程序来处理 api 限制错误

Posted

技术标签:

【中文标题】如何设计 goroutines 程序来处理 api 限制错误【英文标题】:How to design goroutines program to handle api limit error 【发布时间】:2021-11-29 21:38:46 【问题描述】:

刚刚开始了解 goroutine 的强大功能。

我有约 100 个帐户和约 10 个区域,循环它们以使用 golang 创建约 1000 个 goroutine 以提高阅读速度。它运行得太快,以至于达到了 20/秒的 API 返回限制。

如何确保所有的 goroutine 都能维持在最大调用率(20/s)?我不确定哪种 golang 并发方法最适合一起处理错误。

例如:

func readInstance(acc string, region string, wg *sync.WaitGroup) 
    defer wg.Done()
    response, err := client.DescribeInstances(acc, region)
    if err != nil 
        log.Println(err) // API limit exceeding 20
        return
    
    .
    .
    .
    .



func main() 
    accounts := []string"g", "h", "i", ...
    regions := []string"g", "h", "i", ...
    for _, region := range regions 
        for i := 0; i < len(accounts); i++ 
            wg.Add(1)
            go readInstance(accounts[i], region, &wg)
        
    
    wg.Wait()

【问题讨论】:

【参考方案1】:

我想你可以试试这个:https://github.com/uber-go/ratelimit

根据文档,它是并发安全的。

import (
    "fmt"
    "time"

    "go.uber.org/ratelimit"
)

func main() 
    rl := ratelimit.New(100) // per second

    prev := time.Now()
    for i := 0; i < 10; i++ 
        now := rl.Take()
        fmt.Println(i, now.Sub(prev))
        prev = now
    

    // Output:
    // 0 0
    // 1 10ms
    // 2 10ms
    // 3 10ms
    // 4 10ms
    // 5 10ms
    // 6 10ms
    // 7 10ms
    // 8 10ms
    // 9 10ms

【讨论】:

【参考方案2】:

如果您对在特定的实时时间内可以执行的请求数量有一个固定的上限,则可以使用time.NewTicker() 来分隔。

c := time.NewTicker(50 * time.Millisecond)
defer c.Stop()

现在,当您要发出服务器请求时,只需插入

<- c.C

在实际请求之前。

【讨论】:

谢谢!创建了一个全局代码并作为指针传递给所有的 goroutine 工作! Coles,有关如何通过渠道的小改进,请参阅***.com/questions/24868859/…

以上是关于如何设计 goroutines 程序来处理 api 限制错误的主要内容,如果未能解决你的问题,请参考以下文章

golang之context详解

如何在处理结果时正确关闭 Goroutines 中的共享通道

Go教程(十三)goroutine和channel

Go教程(十三)goroutine和channel

Go教程(十三)goroutine和channel

如何关闭多个 goroutine 正在发送的通道?