小编典典

去,tcp太多打开文件调试

go

这是一个简单的Go http(tcp)连接测试脚本

func main() {
    ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello, client")
    }))
    defer ts.Close()
    var wg sync.WaitGroup
    for i := 0; i < 2000; i++ {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            resp, err := http.Get(ts.URL)
            if err != nil {
                panic(err)
            }
            greeting, err := ioutil.ReadAll(resp.Body)
            resp.Body.Close()
            if err != nil {
                panic(err)
            }
            fmt.Printf("%s", i, greeting)
        }(i)
    }
    wg.Wait()
}

如果我在Ubuntu中运行它,我将得到:

panic: Get http://127.0.0.1:33202: dial tcp 127.0.0.1:33202: too many open files

其他帖子说,以确保Close连接,这就是我在这里所做的全部。还有人说,要增加最大连接数的限制ulimit或尝试使用,sudo sysctl -w fs.inotify.max_user_watches=100000但仍然行不通。

如何在单个服务器上运行数百万个tcp连接goroutine?仅在2,000个连接时崩溃。

谢谢,


阅读 310

收藏
2020-07-02

共1个答案

小编典典

我认为您需要更改您的最大文件描述符。我之前在我的一个开发VM上遇到了相同的问题,因此需要更改文件描述符的最大值,而不是更改inotify设置的任何内容。

FWIW,您的程序在我的VM上运行良好。

·> ulimit -n
120000

但是我跑完之后

·> ulimit -n 500
·> ulimit -n
500

我得到:

panic: Get http://127.0.0.1:51227: dial tcp 127.0.0.1:51227: socket: too many open files

不要陷入Praveen的陷阱

注意ulimit!= ulimit -n

➜  cmd git:(wip-poop) ✗ 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 (kbytes)          unlimited
-l: locked-in-memory size (kbytes)  unlimited
-u: processes                       1418
-n: file descriptors                4864
2020-07-02