LoginSignup
14
13

More than 5 years have passed since last update.

microservicesの調査に向けて〜Golang製のzipking tracerのgo-kitを利用してみる

Posted at

1. やりたいこと

以前の投稿で、docker-composeを利用して、zipkinサービスを手元で動かすことができるようになったので、golangでも、zipkinにレコードを登録できるかを試してみようと思いました。

下記を一通り読むと、addsrvのセクションで簡単なサンプルが紹介されていました。

2. やってみた

2-1. ソースコードをダウンロード

git clone https://github.com/go-kit/kit.git

cd kit/examples/addsvc/

2-2. 依存するライブラリをgo getする

go get github.com/go-kit/kit/tracing/zipkin
go get github.com/codahale/hdrhistogram
go get github.com/prometheus/client_golang/prometheus

2-3. ビルドしてサーバを起動する

go build

./addsvc --zipkin.collector.addr=*.*.*.*:9410

2-4. curlで、起動したサーバにGETメソッドを送る

curl  -H "Content-Type: application/json" -L  "http://localhost:8001/sum" -d '{"a":10,"b":12}'

上記を実行すると、下記のようなエラーが出ちゃいました。。

ts=2016-**-**T14:10:40Z caller=stdlib.go:89 file="http: panic serving [::1" msg="]:50391: interface conversion: interface {} is server.SumRequest, not *server.SumRequest"

2-5. でもzipkinのuiを見てみる

addsvcというサービスがトレースされていることが確認できました。

スクリーンショット 2016-03-23 23.27.57.png

まだ、コミットが直近でも入っているようなので発展途上なのかもしれません。もうちょっと時間をおいてまた見てみようと思います。

3. ちょっとだけソースも眺めてみた

main.goを起点に、httpサーバをgolangで立てたときにどのようにトレーサーを仕込んでいくのかを見てみました。

3-1. zipkin collectorの変数を生成

まず、tracer自体については、go-kit/kit/tracing/zipkinパッケージのzipkinzipkin.NewScribeCollectorを読んで生成しているようでした。

main.go
    // package tracing
    var collector zipkin.Collector
    {
        zipkinLogger := log.NewContext(logger).With("component", "zipkin")
        collector = loggingCollector{zipkinLogger} // TODO(pb)
        if *zipkinCollectorAddr != "" {
            var err error
            if collector, err = zipkin.NewScribeCollector(
                *zipkinCollectorAddr,
                *zipkinCollectorTimeout,
                zipkin.ScribeBatchSize(*zipkinCollectorBatchSize),
                zipkin.ScribeBatchInterval(*zipkinCollectorBatchInterval),
                zipkin.ScribeLogger(zipkinLogger),
            ); err != nil {
                zipkinLogger.Log("err", err)
                os.Exit(1)
            }
        }
    }

3-2. httpリクエストをトレースする

上記を、おそらくhttpのリクエストに食わせていると思い眺めて、とってもざっくりな理解ですが、

  1. zipkin.AnnotateServer(newSumSpan, collector)(sum)で処理実行のサーバとdurationの開始をハンドル
  2. net/httpのmux.Handlerに、zipkintのtransport/httpパッケージのファンクションをかまして、終了をキャッチ

のような感触を得ました。

main.go
        var (
            transportLogger = log.NewContext(logger).With("transport", "HTTP/JSON")
            tracingLogger   = log.NewContext(transportLogger).With("component", "tracing")
            newSumSpan      = zipkin.MakeNewSpanFunc(*zipkinHostPort, *zipkinServiceName, "sum")
            newConcatSpan   = zipkin.MakeNewSpanFunc(*zipkinHostPort, *zipkinServiceName, "concat")
            traceSum        = zipkin.ToContext(newSumSpan, tracingLogger)
            traceConcat     = zipkin.ToContext(newConcatSpan, tracingLogger)
            mux             = http.NewServeMux()
            sum, concat     endpoint.Endpoint
        )

        sum = makeSumEndpoint(svc)
        sum = zipkin.AnnotateServer(newSumSpan, collector)(sum)
        mux.Handle("/sum", httptransport.NewServer(
            root,
            sum,
            server.DecodeSumRequest,
            server.EncodeSumResponse,
            httptransport.ServerBefore(traceSum),
            httptransport.ServerErrorLogger(transportLogger),
        ))

4. 所感

  • Golangでもできるんだー、と思いました。Elixir/Phoenixでもできないのかな。
  • net/httpでrouteごとに上記のように実装するのはちょっと冗長かも、と思いました。
  • go getが動かずに動作確認できませんでしたが、go-zipkinだと上記のような冗長な箇所が解消されているのかな、とちょっと期待。ソース見てみよー。
  • いろいろ眺めてみたけれど満足に動くライブラリとかサンプルが少ないような。。みんなトレーシングはfluentなどのロギングベースでいくのかな。mix inとかDIみたいにさりげなくzipkinのような仕組みをフレームワークに組み込めたら素敵だと思うのだけれども。。。

5. 参考


本日は以上となります。

14
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13