net / http Транспорт, превышающий MaxConnsPerHost - PullRequest
2 голосов
/ 20 марта 2019

У меня есть простая программа ниже, которая представляет собой простой HTTP-клиент и сервер.Я проверяю, работает ли MaxConnsPerHost в http.Transport, введенном в Go 1.11 , как рекламируется.Однако, когда я запускаю код более 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, уже превышают 50.

PS У нас проблема в одномнаших услуг, которые ужасно пропускают УСТАНОВЛЕННЫЕ соединения, даже если мы правильно закрываем тело ответа.В настоящее время он построен с использованием Go 1.10 , и я надеялся, что Go 1.11 MaxConnsPerHost будет решением, но, похоже, он также трескается при большой нагрузке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...