为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
隔江千里 2021-12-06 19:42:20
我一直在尝试为我的应用程序制作一个速率限制器并遇到了这段代码。读完之后,我仍然无法理解它究竟做了什么。我目前的理解: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 secondsfunc 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 minutesfunc 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}
查看完整描述

1 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

我认为您不应该使用此代码来学习任何有用的东西。我不确定,但它似乎试图限制请求率,但这是错误的。它允许发出一定数量的请求,然后等待一个时间间隔。在时间间隔之后,它允许您再次提出请求。所有这些都是以非常复杂的方式完成的。

但它可能会导致非常奇怪的场景。假设您制作 1req/h 并且您的限制是 500req/20sec。然后此代码将导致您在 500 小时后等待 20 秒并允许再次发出请求。

checkTimeTrigger 如果有的话,从 RateChan.TriggerChan 中删除一条消息,如果没有,则不执行任何操作并立即返回。

这段代码显然不是DRY。如果您想限制请求率,最好使用https://godoc.org/golang.org/x/time/rate


查看完整回答
反对 回复 2021-12-06
  • 1 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信