https://qiita.com/kitauji/items/b4e8a48c75bf01ccc9f0

この記事について

net/http パッケージの Client は内部で TCP コネクションプールを持ち、コネクションのキャッシュ・再利用を行う。リクエスト送信時は、プール内に空きコネクションがあればそれを利用する。

そのため、Client は何度も作るのではなく使いまわした方がよい。この記事ではそのコネクションプールの仕組みについてまとめる。

なお、HTTP/1.x と HTTP/2 では TCP コネクションの使い方が全く異なるため、HTTP/1.x ついてのみ記載する。

まとめ

Untitled

初めに Transport について

Client は Do()メソッドの呼び出しによりリクエストを送信するが、実際にTCPコネクションを張って(つまり Dial して)、リクエストの送受信を行うのは RoundTripper インターフェースを実装したオブジェクトである。

type Client struct {
    // Transport specifies the mechanism by which individual
    // HTTP requests are made.
    // If nil, DefaultTransport is used.
    Transport RoundTripper
    // ...
}

net/http では RoundTripper として Transport という構造体が実装されており、この Transport が TCP コネクションを管理するコネクションプールを持っている。

なお、Client へ明示的に RoundTripper が指定されなければデフォルトとして、以下の DefaultTransport が使われる。

go/src/net/http/transport.go

var DefaultTransport RoundTripper = &Transport{
    Proxy: ProxyFromEnvironment,
    DialContext: (&net.Dialer{
        Timeout:   30 * time.Second,
        KeepAlive: 30 * time.Second,
        DualStack: true,
    }).DialContext,
    ForceAttemptHTTP2:     true,
    MaxIdleConns:          100,
    IdleConnTimeout:       90 * time.Second,
    TLSHandshakeTimeout:   10 * time.Second,
    ExpectContinueTimeout: 1 * time.Second,
}

コネクション管理