net / http传输超过MaxConnsPerHost

时间:2019-03-20 10:02:46

标签: go

我下面有一个简单的程序,它是一个简单的HTTP客户端和服务器。我正在测试 Go 1.11 中引入的MaxConnsPerHost中的http.Transport是否按广告要求工作。但是,当我运行代码超过10-30分钟时,已建立的连接会慢慢超过设置的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")

}

长时间运行后,netstat报告的ESTABLISHED连接已超过50。

P.S。我们的其中一项服务存在问题,即使我们已正确关闭响应的正文,该服务也会严重泄漏已建立的连接。目前,它是使用 Go 1.10 构建的,我希望 Go 1.11 MaxConnsPerHost是一个解决方案,但它似乎在重负载下也会裂开。

0 个答案:

没有答案