2017-05-04 90 views
1

我有一個需要使用goroutine同時觸發HTTP請求的URL列表。無論如何要檢查並限制每秒發送多少個HTTP請求?是否可以限制每秒運行多少個goroutines?

+3

圍棋不能限制全球範圍夠程。如果你提出http請求,你不能自己限制它們嗎? – JimB

+0

@JimB:我應該如何限制他們?例如,我希望程序每秒發送少於或等於10個http請求。 – Pig

+2

使用可以使用信號量來限制最大併發請求,和/或使用[token bucket](https://en.wikipedia.org/wiki/Token_bucket)或[leaky bucket](https:/ /en.wikipedia.org/wiki/Leaky_bucket)。 – JimB

回答

6

Go中的一個非常簡單的版本將是一個使用通道和goroutine的​​3210算法的改編。在發出請求之前向rate通道添加令牌將檢查速率並阻止速率限制器是否已滿。

// create a buffered channel. 
// The capacity of the channel is maximum burst that can be made. 
rate := make(chan struct{}, 10) 
for i := 0; i < cap(rate); i++ { 
    rate <- struct{}{} 
} 

// leaky bucket 
go func() { 
    ticker := time.NewTicker(100 * time.Millisecond) 
    for range ticker.C { 
     <-rate 
    } 
}() 

由於一系列的花費比平均速率較長最終會被併發請求,您可能需要限制併發了。您可以添加第二個通道作爲信號量,在發出請求之前向信號量添加一個標記,並在完成時刪除它。

// limit concurrency to 5 
semaphore := make(chan struct{}, 5) 

// in request function 
semaphore <- struct{}{} 
defer func() { 
    <-semaphore 
}() 

稍微更完整的例子是在這裏:

https://play.golang.org/p/ZrTPLcdeDF

相關問題