Go client で http を trace する

よく分からない挙動に立ち向かう


Posted on 2019年 8月 20日 (火)
Tags golang, http, httptrace, network, troubleshooting
golang, http, httptrace, network, troubleshooting

Go client で http を trace する

よく分からない挙動に立ち向かう

Day2 はつらい 😢

またその話か。

http は難しい

http だけでもヘッダやボディを含めて色々問題の原因となりうるものがある。

その上で、tcp, ip, ネットワーク、物理レイヤーが原因となりうる 😇

事件は internet のつながらない環境で起こった 🔥

ruby のクライアントからオブジェクトストレージへのアクセスが遅い。

しかし、問題はクライアントか、サーバーか、ネットワークか…

え、ruby の実行環境持っていかないといけないの?

internet がつながらない -> ruby をインストール

-> 解決と思いきや、gem が足りない -> gem インストール

-> 解決と思いきや、native build が必要 -> gcc, make をインストール -> 失敗 😇

え、ストレージチームも確認したいって?

ruby の環境を作って、gem インストールしてもらってつらい…

そこで、奥さん。バイナリ簡単に作れる Go

httptrace-client

Go の httptrace パッケージを使っただけのサンプル。

go-zen-chu/httptrace-client

httptrace package

client での http header の状態のみならず、DNS の問い合わせ、connection の開始と完了などの状態を trace できる。

src/net/http/httptrace/trace.go

使いそうなメソッド定義

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
type ClientTrace struct {
    GetConn func(hostPort string)
    GotConn func(GotConnInfo)
    GotFirstResponseByte func()
    DNSStart func(DNSStartInfo)
    DNSDone func(DNSDoneInfo)
    ConnectStart func(network, addr string)
    ConnectDone func(network, addr string, err error)
    TLSHandshakeStart func()
    TLSHandshakeDone func(tls.ConnectionState, error)
    WroteHeaderField func(key string, value []string)
    WroteHeaders func()
    WroteRequest func(WroteRequestInfo)
}

google へ https してみる

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
2019/08/17 18:37:54.178798 GetConn: google.com:443
2019/08/17 18:37:54.179219 DNSStart: {Host:google.com}
2019/08/17 18:37:54.181677 DNSDone: {Addrs:[{IP:216.58.196.238 Zone:}
2019/08/17 18:37:54.288372 TLSHandshakeStart
2019/08/17 18:37:54.942141 TLSHandshakeDone: {Version:771 HandshakeComplete:true DidResume:false CipherSuite:49195 NegotiatedProtocol:h2 NegotiatedProtocolIsMutual:true }
2019/08/17 18:37:54.942706 GotConn:
2019/08/17 18:37:54.942855 WroteHeaderField: :authority [google.com]
2019/08/17 18:37:54.942865 WroteHeaderField: :method [GET]
2019/08/17 18:37:54.942870 WroteHeaderField: :path [/]
2019/08/17 18:37:54.942876 WroteHeaderField: :scheme [https]
2019/08/17 18:37:54.942886 WroteHeaderField: accept-encoding [gzip]
2019/08/17 18:37:54.942892 WroteHeaderField: user-agent [Go-http-client/2.0]
2019/08/17 18:37:54.942956 WroteRequest: {Err:<nil>}
2019/08/17 18:37:55.170277 GotFirstResponseByte

tcp dump も取っておこう 📃

tcpdump の様子

Linux 向けに build して、クライアントとサーバー側で動作確認 🤝

1
GOARCH="amd64" GOOS="linux" go build main.go

day 2 へ立ち向かおう 😇

FIN

Share


See also