我有这个测试程序,它将并行获取url,但是当我将并行数增加到大约1040时,我开始出现lookup www.httpbin.org: no such host
错误。
经过一番Google搜索后,我发现其他人说不关闭响应会导致问题,但是我确实使用res.Body.Close()
关闭了它。
这是什么问题非常感谢。
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func get(url string) ([]byte, error) {
client := &http.Client{}
req, _ := http.NewRequest("GET", url, nil)
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return nil, err
}
bytes, read_err := ioutil.ReadAll(res.Body)
res.Body.Close()
fmt.Println(bytes)
return bytes, read_err
}
func main() {
for i := 0; i < 1040; i++ {
go get(fmt.Sprintf("http://www.httpbin.org/get?a=%d", i))
}
}
最佳答案
那是因为您的代码中最多可能有1040个并发调用,因此您很可能处于1040主体打开且尚未关闭的状态。
您需要限制使用的goroutine的数量。
这是一个最大可能限制为100个并发调用的解决方案:
func getThemAll() {
nbConcurrentGet := 100
urls := make(chan string, nbConcurrentGet)
for i := 0; i < nbConcurrentGet; i++ {
go func (){
for url := range urls {
get(url)
}
}()
}
for i:=0; i<1040; i++ {
urls <- fmt.Sprintf("http://www.httpbin.org/get?a=%d", i)
}
}
如果在程序的主函数中调用此函数,则它可能在所有任务完成之前停止。您可以使用
sync.WaitGroup
来防止它:func main() {
nbConcurrentGet := 100
urls := make(chan string, nbConcurrentGet)
var wg sync.WaitGroup
for i := 0; i < nbConcurrentGet; i++ {
go func (){
for url := range urls {
get(url)
wg.Done()
}
}()
}
for i:=0; i<1040; i++ {
wg.Add(1)
urls <- fmt.Sprintf("http://www.httpbin.org/get?a=%d", i)
}
wg.Wait()
fmt.Println("Finished")
}