Go

  • responseを捨ててしまうと、resp.Body.Close() ができなくなるのでだめ
  • 最後まで読み切ってCloseしてないとkeep-aliveしない
  • for-loopの中でリクエストする場合きっちり毎回Closeする

Goのnet/httpのclientでなぜresponseBodyをClose、読み切らなくてはいけないのか

  1. responseBodyをCloseしないとコネクションがブロックしてしまい再利用されず、古い接続が残ったまま、新しく接続するたびに新しいGoroutineとファイルディスクリプタを作ってしまう
  2. responseBodyを読み切らないとkeepAliveされずコネクションが終了してしまい再利用されず、接続のたびに新しい接続を作ってしまう。

Connection re-use in Golang with http.Client - stuartleeks.com

  • bodyを読み切り、Closeを行う

DefaultClient を使う:

    // Uses http.DefaultClient which in turn uses the same http.DefaultTransport instance
    http.Get("http://example.com")

Transport を指定しない(DefaultTransport が使われる):

    // Transport not set, so http.DefaultTransport instance is used
    client := &http.Client{}
    client.Get("http://example.com")

同じ Transport を使う:

    // Transport set to a cached value
    client := &http.Client{
        Transport: transport, // assuming that transport is a fixed value for this example!
    }
    client.Get("http://example.com")

再利用されないケース: http.Client ごとに Transport を作る

    // New Transport for each client/call means that connections cannot be re-used
    // This leads to port exhaustion under load :-(
    client := &http.Client{
        Transport: &http.Transport{
            // insert config here
        },
    }
    client.Get("http://example.com")