won*_*ng2 10 linux concurrency networking http go
我有这个测试程序,它将获取url并行,但当我将并行数增加到大约1040时,我开始得到lookup www.httpbin.org: no such host错误.
在一些谷歌之后,我发现其他人说没有关闭响应会导致问题,但我确实关闭了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))
}
}
Run Code Online (Sandbox Code Playgroud)
Den*_*ret 11
这是因为您的代码中最多可能有1040个并发调用,因此您很可能处于打开1040正文并且尚未关闭的状态.
您需要限制使用的goroutines数量.
这是一个可能的解决方案,限制为100个并发调用max:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
如果在程序的main函数中调用它,它可能会在所有任务完成之前停止.您可以使用a 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")
}
Run Code Online (Sandbox Code Playgroud)
sim*_*nke 11
从技术上讲,您的过程受限(通过内核)到大约1000个打开的文件描述符.根据上下文,您可能需要增加此数字.
在你的shell运行中(注意最后一行):
$ ulimit -a
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) 0
-v: address space (kb) unlimited
-l: locked-in-memory size (kb) unlimited
-u: processes 709
-n: file descriptors 2560
Run Code Online (Sandbox Code Playgroud)
增加(临时):
$ ulimit -n 5000
(no output)
Run Code Online (Sandbox Code Playgroud)
然后验证fd限制:
$ ulimit -n
5000
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6878 次 |
| 最近记录: |