我用 GO 写了一个很简单的反向代理程序,代码如下:
func main() {
go func() {
log.Fatal( http.ListenAndServe(":5050", nil))
}()
link, err := url.Parse("http://127.0.0.1:8908")
if err != nil {
log.Fatal(err)
}
log.Fatal( http.ListenAndServe(":10086", httputil.NewSingleHostReverseProxy(link)))
}
端口 8908 后边是一个 NodeJS socket.io 服务端,现在我通过 NodeJS 向 10086 端口同时发起 1000 个 websocket 连接,这些链接均会被代理到 8908 端口服务,然后将所有连接断开,重复几轮后可见控制台报如下错误:
2022/01/18 14:06:54 http: proxy error: dial tcp 127.0.0.1:8908: connectex: Only one usage of each socket address (protocol/network address/port) is normally permitted.
此时通过 windows 资源监视器可看到反向代理程序线程数为 298 ,通过 Process Explorer 可以看到 Handles 数为 1855 ,并且存在大量 Thread 。
再次建立连接再断开,反向代理程序的线程数持续增长,通过 pprof 可见 threadcreate 此时达到了惊人的 472 ,并一直保持。
似乎是系统端口数量限制导致的错误,然后错误导致线程未被回收?
我是 GO 新手,大家有遇到过这个问题吗?