猿问

无法理解此速率限制器的工作原理

我一直在尝试为我的应用程序制作一个速率限制器并遇到了这段代码。读完之后,我仍然无法理解它究竟做了什么。


我目前的理解:


1) 调用 SetSmallRateLimit 和 SetLongRateLimit 以初始化通道并开始在 goroutine 中运行处理程序。


2)当requestAndUnmarshal被调用时,checkRateLimiter向队列通道发送信号。


我不明白的是:


1) RateLimitHandler 休眠 time.After(pertime) 的持续时间,然后清除队列通道。不确定 triggerWatcher 和 returnChan 在做什么。


2) checkTimeTrigger - 不明白这个函数在做什么或其目的。


var (

    smallRateChan   rateChan

    longRateChan    rateChan

)


type rateChan struct {

    RateQueue   chan bool

    TriggerChan chan bool

}


//10 requests every 10 seconds

func SetSmallRateLimit(numrequests int, pertime time.Duration) {

    smallRateChan = rateChan{

        RateQueue:   make(chan bool, numrequests),

        TriggerChan: make(chan bool),

    }

    go rateLimitHandler(smallRateChan, pertime)

}


//500 requests every 10 minutes

func SetLongRateLimit(numrequests int, pertime time.Duration) {

    longRateChan = rateChan{

        RateQueue:   make(chan bool, numrequests),

        TriggerChan: make(chan bool),

    }

    go rateLimitHandler(longRateChan, pertime)

}


func rateLimitHandler(RateChan rateChan, pertime time.Duration) {

    returnChan := make(chan bool)

    go timeTriggerWatcher(RateChan.TriggerChan, returnChan)

    for {

        <-returnChan

        <-time.After(pertime)

        go timeTriggerWatcher(RateChan.TriggerChan, returnChan)

        length := len(RateChan.RateQueue)

        for i := 0; i < length; i++ {

            <-RateChan.RateQueue

        }

    }

}


func timeTriggerWatcher(timeTrigger chan bool, returnChan chan bool) {

    timeTrigger <- true

    returnChan <- true

}


func requestAndUnmarshal(requestURL string, v interface{}) (err error) {

    checkRateLimiter(smallRateChan)

    checkRateLimiter(longRateChan)

    resp, err := http.Get(requestURL)

    defer resp.Body.Close()

    if err != nil {

        return

    }

    checkTimeTrigger(smallRateChan)

    checkTimeTrigger(longRateChan)

    if err != nil {

        return

    }

    return

}


隔江千里
浏览 157回答 1
1回答

万千封印

我认为您不应该使用此代码来学习任何有用的东西。我不确定,但它似乎试图限制请求率,但这是错误的。它允许发出一定数量的请求,然后等待一个时间间隔。在时间间隔之后,它允许您再次提出请求。所有这些都是以非常复杂的方式完成的。但它可能会导致非常奇怪的场景。假设您制作 1req/h 并且您的限制是 500req/20sec。然后此代码将导致您在 500 小时后等待 20 秒并允许再次发出请求。checkTimeTrigger&nbsp;如果有的话,从 RateChan.TriggerChan 中删除一条消息,如果没有,则不执行任何操作并立即返回。这段代码显然不是DRY。如果您想限制请求率,最好使用https://godoc.org/golang.org/x/time/rate。
随时随地看视频慕课网APP

相关分类

Go
我要回答