go-httpstatでリクエストにかかった時間の割合をみる
golangでhttpリクエストするときにkeepaliveにしたらどれくらいリクエストにかかる時間減るのかを知りたかったのだが、こういうライブラリがあるのを知った。
https://github.com/tcnksm/go-httpstat
実際は net/http/httptrace をラップしているだけっぽい。ただこれくらいのコードで情報が出てきて便利。
package main
import (
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"time"
"github.com/tcnksm/go-httpstat"
)
func main() {
args := os.Args
if len(args) < 2 {
log.Fatalf("Usage: go run main.go URL")
}
req, err := http.NewRequest("GET", args[1], nil)
if err != nil {
log.Fatal(err)
}
var result httpstat.Result
ctx := httpstat.WithHTTPStat(req.Context(), &result)
req = req.WithContext(ctx)
client := http.DefaultClient
res, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
log.Fatal(err)
}
res.Body.Close()
result.End(time.Now())
fmt.Printf("%+v\n", result)
}
DNS lookup: 0 ms
TCP connection: 178 ms
TLS handshake: 266 ms
Server processing: 409 ms
Content transfer: 0 ms
Name Lookup: 0 ms
Connect: 179 ms
Pre Transfer: 446 ms
Start Transfer: 409 ms
Total: 409 ms
当然と言われれば当然なんだけど、TCPの3way handshakeだけでも結構時間かかるんだなというのがわかった。サーバーのコンテンツ生成がほぼ全ての時間かかってるイメージだったが、こうやって自分で計測してみると全然そんなことないんだなというのがわかる。そりゃkeepaliveみたいなの使ってコネクション使いまわしたくなるわけだ。
あとローカルでサーバーたててもDNSルックアップにかかる時間はほとんどない。そういう時に手軽にローカルじゃない環境作るのにngrok使えばええという知見も得られた。