我有一组URL,需要使用goroutine并发发送HTTP请求。有没有办法检查并限制每秒发送的HTTP请求数量?
使用通道和goroutine来适应漏桶算法的一种非常简单的Go版本。在发出请求之前,从rate
通道接收一个令牌将检查速率,并在速率限制器为空时阻塞。
// create a buffered channel.
// The capacity of the channel is maximum burst that can be made.
rate := make(chan struct{}, 10)
go func() {
ticker := time.NewTicker(100 * time.Millisecond)
for range ticker.C {
rate <- struct{}{}
}
}()
如果一系列请求的时间超过了平均速率,则这些请求将变成并发请求,因此您可能还需要限制并发。您可以添加第二个通道作为信号量,在发出请求之前向信号量添加一个令牌,并在请求完成后将其删除。
// limit concurrency to 5
semaphore := make(chan struct{}, 5)
// in request function
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
这里有一个稍微更完整的例子:
golang.org/x/time/rate
的“稍微完整一些的示例”:https://play.golang.org/p/44rUKLdTPbO - Dave Cint
意味着int
的值具有意义,但实际上它并没有。空的struct{}
更明显地只是一个不透明的标记。 - JimB这是一个简单的包,可以帮助您限制允许同时运行的goroutine数量。请查看https://github.com/zenthangplus/goccm
示例:
package main
import (
"fmt"
"goccm"
"time"
)
func main() {
// Limit 3 goroutines to run concurrently.
c := goccm.New(3)
for i := 1; i <= 10; i++ {
// This function have to call before any goroutine
c.Wait()
go func(i int) {
fmt.Printf("Job %d is running\n", i)
time.Sleep(2 * time.Second)
// This function have to when a goroutine has finished
// Or you can use `defer c.Done()` at the top of goroutine.
c.Done()
}(i)
}
// This function have to call to ensure all goroutines have finished
// after close the main program.
c.WaitAllDone()
}