我有一个URL列表,我需要使用goroutine同时触发HTTP请求.无论如何都要检查并限制每秒发送多少HTTP请求?
Go中的一个非常简单的版本是使用通道和goroutine 的Leaky Bucket算法的改编.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{}{}
}
}()
Run Code Online (Sandbox Code Playgroud)
由于一系列超过平均速率的请求最终会并发,因此您可能也需要限制并发性.您可以添加第二个通道作为信号量,在发出请求之前向信号量添加一个标记,并在完成后将其删除.
// limit concurrency to 5
semaphore := make(chan struct{}, 5)
// in request function
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
Run Code Online (Sandbox Code Playgroud)
这里有一个稍微完整的例子:
https://play.golang.org/p/ZrTPLcdeDF