我有一个简单的程序,下面是一个简单的 HTTP 客户端和服务器。我正在测试Go 1.11MaxConnsPerHost中http.Transport引入的功能是否如宣传的那样工作。但是,当我运行代码超过 10-30 分钟时,ESTABLISHED 连接慢慢超过了设置。难道我做错了什么?MaxConnsPerHost
package main
import (
"io/ioutil"
"log"
"net"
"net/http"
"time"
)
func main() {
// Server
//
go func() {
if err := http.ListenAndServe(":8081", http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hi"))
},
)); err != nil {
log.Fatal(err)
}
}()
// Client settings
//
c := &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
MaxConnsPerHost: 50,
},
}
// Worker loop
//
threads := 500
for i := 0; i < threads; i++ {
go func() {
for {
req, err := http.NewRequest("GET", "http://localhost:8081", nil)
if err != nil {
log.Fatal(err)
}
res, err := c.Do(req)
if err != nil {
log.Fatal(err)
}
if _, err := ioutil.ReadAll(res.Body); err != nil {
log.Fatal(err)
}
res.Body.Close()
}
}()
}
var done chan bool
<-done
log.Println("Done")
}
Run Code Online (Sandbox Code Playgroud)
运行了很长时间后,报告的ESTABLISHED连接netstat已经超过50个。
PS 我们的一项服务存在问题,即使我们正确关闭响应的正文,该服务也会严重泄漏已建立的连接。它目前使用Go 1.10构建,我希望Go 1.11 MaxConnsPerHost能成为一个解决方案,但它似乎在重负载下也会崩溃。
难道我做错了什么?
看来这个错误已经在更新的 go 版本中得到解决,我无法用以下命令重现这个问题:
$ go version
go version go1.17.1 linux/amd64
Run Code Online (Sandbox Code Playgroud)
监控:
watch -n 3 'ss -tn | grep :8081 | sort -k 3,3n | tee >(wc -l) | tail ;
ps -eo pid,etime,cmd | grep "leaky[-]server"'
Run Code Online (Sandbox Code Playgroud)
运行服务器:
go run leaky-server.go
Run Code Online (Sandbox Code Playgroud)
2.5小时后的样本输出:
Every 3.0s: ss -tn | grep :8081 | sor... balmora: Sun Oct 31 12:38:52 2021
ESTAB 0 118 [::1]:8081 [::1]:43814
ESTAB 0 118 [::1]:8081 [::1]:43818
ESTAB 0 118 [::1]:8081 [::1]:43822
ESTAB 0 118 [::1]:8081 [::1]:43824
ESTAB 0 118 [::1]:8081 [::1]:43830
ESTAB 0 118 [::1]:8081 [::1]:43834
ESTAB 0 118 [::1]:8081 [::1]:43836
ESTAB 0 118 [::1]:8081 [::1]:43838
ESTAB 0 118 [::1]:8081 [::1]:43844
100
536182 02:30:03 go run leaky-server.go
536269 02:30:03 /tmp/go-build2453595122/b001/exe/leaky-server
Run Code Online (Sandbox Code Playgroud)