是否可以限制每秒运行多少个goroutine?

时间:2017-05-04 17:33:17

标签: http go

我有一个URL列表,我需要使用goroutine来同时触发HTTP请求。无论如何都要检查并限制每秒发送多少HTTP请求?

2 个答案:

答案 0 :(得分:7)

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{}{}
    }
}()

由于一系列超过平均速率的请求最终会并发,因此您可能还需要限制并发性。您可以添加第二个通道作为信号量,在发出请求之前向信号量添加一个标记,并在完成后将其删除。

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

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

这里有一个稍微完整的例子:

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

答案 1 :(得分:-1)

这是一个简单的软件包,可帮助您限制允许并行运行的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()
}