Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ゆるふわ分散トレースはじめました / start casual distributed trace

ゆるふわ分散トレースはじめました / start casual distributed trace

【BASE社合同勉強会】コネヒトマルシェオンライン「事業を支えるWeb開発」
https://connehito.connpass.com/event/176890/

スライド資料内のリンクなどはこちらにまとめている。
https://budougumi0617.github.io/2020/06/04/connehito_marche/

Yoichiro Shimizu

June 04, 2020
Tweet

More Decks by Yoichiro Shimizu

Other Decks in Programming

Transcript

  1. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    2020/06/04 コネヒトマルシェ オンライン
    Yoichiro Shimizu @budougumi0617
    ゆるふわ分散トレースはじめました

    View Slide

  2. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    自己紹介
    2
    ● 清水 陽一郎 @budougumi0617
    ● BASE BANK, Inc. Dev Division
    ○ Go/PHP/Python/AWS etc...
    ● コミュニティ: golang.tokyo / Go Conference etc...
    ● 趣味: ボルダリング/毎週ブログを書くこと
    ○ https://budougumi0617.github.io/
    Go Conferenece

    View Slide

  3. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    はじめに
    3

    View Slide

  4. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc. 4
    ● なぜ分散トレースが必要なのか
    ○ 舞台となる事業のアーキテクチャ構成
    ● 分散トレースとは何なのか
    ○ 分散トレースの概要
    ○ ”ゆるふわ”とは
    ● どうやって実現したのか
    ○ Context patternを使ったGoとPythonの実装
    ● 導入してどうだったか
    アジェンダ

    View Slide

  5. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc. 5
    ● 複数サービスでシステムを構成したときに生じる悩みを共有する
    ● 分散トレースについてざっくり知ってもらう
    ● インフラ構成の変更、追加予算なしで始める方法の紹介
    ● リクエストIDを付けるだけでも解析が便利になることを共有する
    今日のゴール

    View Slide

  6. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    なぜ分散トレースが
    必要なのか
    6

    View Slide

  7. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    売れたタイミングで自動支払い
    即時で資金調達できるという体験
    100万店舗のデータから
    BASE独自の売上予測を開発
    リスクなく、即時で資金調達できる金融サービス
    https://thebase.in/yellbank
    7
    YELL BANK

    View Slide

  8. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    BASE本体 分析データ
    データ分析基盤
    API
    データ処理系
    API
    ログ分析
    エラーレポート
    8
    YELL BANKのアーキテクチャ構成
    CWL Kibana
    Raygun

    View Slide

  9. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● どのログ同士(エラーレポート)が関連しているのかわからない
    9
    エラーが発生したとき
    エラー発生
     エラーに対応している
     ログはどれ?
    どれ? どれ?

    View Slide

  10. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    時刻で絞って探すのを止めたかった
    分散トレースしたい!
    10

    View Slide

  11. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    分散トレースとは
    11

    View Slide

  12. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● MicroservicesのObservabilityに関するパターンのひとつ
    ● 個々の外部リクエストに一意なIDを与え、そのリクエストがサービス間をどのよう
    にやり取りされたのか可視化、解析する
    12
    分散トレース(Distributed tracing pattern)
    Image from https://www.jaegertracing.io/docs/1.17/architecture/

    View Slide

  13. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● Pattern: Distributed tracing
    ○ https://microservices.io/patterns/observability/distribute
    d-tracing.html
    ● W3C Trace context
    ○ https://www.w3.org/TR/trace-context/
    13
    分散トレース(Distributed tracing pattern)

    View Slide

  14. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● SaaSを使う
    ○ New Relic, Datadog etc
    ● OSSを組み合わせる
    ○ OpenTelemetry/OpenCensus, Jeager, Istio etc
    ● クラウドベンダーの仕組みに乗っかる
    ○ AWS X-Ray, GCP Cloud trace etc
    ● それなりに仰々しい追加・変更が必要になる
    14
    分散トレースの実現方法

    View Slide

  15. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ゆるくふわっと始めてみる
    15

    View Slide

  16. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● (現時点では)そこまで困っていなかった
    ○ 1ヶ月に1回あると楽だなと思うくらい
    ○ パフォーマンス面でとくに問題ない
    ● 他のOKRタスクの片手間でやれるくらいでやりたかった
    ○ 追加コストを払ってまではやりたくない
    ○ インフラ構成の追加・変更してまでやりたくない
    ○ 正式に導入するときに容易に廃棄可能であってほしい
    16
    そんなにガッツリやりたくなかった

    View Slide

  17. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● ログ分析やエラーレポートは既存の基盤をそのまま使う
    ○ 各サービスごとにKibanaやCWLを確認する現状は維持
    ● リクエストIDを付与することでログとエラーの関連性を可視化
    ● ドリルダウンみたいなリッチな可視化は今回は諦める
    17
    ゆるくふわっと始める分散トレース

    View Slide

  18. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ゆるふわ分散トレースの方針



    リクエストからIDを取り出す
    IDをサービス全体に伝播させる
    IDをログやエラーに埋め込む
    18

    View Slide

  19. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    サービス間で
    リクエストIDをやりとりする
    19

    View Slide

  20. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc. 20
    リクエストIDでログ同士、エラーの関連性を可視化
    リクエストID生成
    with ID
    with ID
    with ID with ID
    with ID
    ● リクエストごとに各ログ出力、エラーレポートが一意なIDを内包
    with ID

    View Slide

  21. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc. 21
    ログやエラーにリクエストIDを伝播させる
    ● 操作の起点でリクエストIDを生成する
    ○ PHPからGoに送信するリクエストにリクエストIDを付与
    ● GoはPHPからもらったリクエストIDをPythonに送信する
    ● Go/Pythonサービス内でリクエストIDを伝播するようにする
    ● ログやエラーレポートにリクエストIDをいれる

    View Slide

  22. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ここでちょっと問題
    レイヤードアーキテクチャでは
    リクエストヘッダーにアクセスできる箇所は限られる
    22

    View Slide

  23. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● BANKのサービスはレイヤードアーキテクチャ構成になっている
    ○ GoでのAPI開発現場のアーキテクチャ実装事例(Pythonもほぼ同じ)
    ■ https://speakerdeck.com/hgsgtk/go-api-architecture-practical-example
    23
    レイヤードアーキテクチャ内でリクエストIDを使う

    View Slide

  24. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● コントローラ層以外でHTTPリクエストは参照できない
    ● ドメイン層やサービス層でもリクエストIDを参照したい
    ○ すべての関数や引数にリクエストIDを直接含めるのは嫌
    24
    レイヤードアーキテクチャ内でリクエストIDを使う

    View Slide

  25. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    Context pattern
    25

    View Slide

  26. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc. 26
    Context pattern
    ● 特定の条件下に閉じた情報を透過的にやりとりするパターン
    ○ Go(1.7~)やPython(3.7~)で標準で提供されている
    ■ https://golang.org/pkg/context/
    ■ https://docs.python.org/ja/3/library/contextvars.html
    ○ J2EE、AndroidやWPF(C#)でもあるパターン
    ■ https://docs.oracle.com/javase/jp/8/docs/api/org/omg/CORBA/Context.html
    ■ https://developer.android.com/reference/android/content/Context.html
    ■ https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.frameworkelement.datacontext
    ○ Stateパターンと似ているが、「状態」だけではない

    View Slide

  27. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    GoでContextを使う
    27

    View Slide

  28. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● 透過的に値をやり取りするときにつかう
    ○ キャンセルやタイムアウトを伝播させるときにも使われる
    ● 関数やメソッドの第一引数にcontext.Contextを含める
    ○ [Go] context.TODO()を使って漸進的にcontext対応を始める
    ■ https://budougumi0617.github.io/2020/02/21/use-context/
    28
    GoでContextを使う

    View Slide

  29. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● MiddlewareでcontextにリクエストIDを注入しておく
    ○ Middlewareはハンドラーに対する共通の前処理
    29
    GoでContextを使う

    View Slide

  30. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● ロギングやエラーレポート送信時にcontextからリクエストIDを
    取り出す
    ● 他サービス呼び出し時にはcontextから取り出してHTTPヘッダー
    にリクエストIDを付与する
    ● アクセスログにもリクエストIDを付与する
    30
    GoでContextを使う

    View Slide

  31. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● ロギングやエラーレポート送信時にcontextからリクエストIDを
    取り出す
    31
    GoでContextを使う

    View Slide

  32. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    Python(aiohttp)で
    Contextを使う
    32

    View Slide

  33. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● Middleware(ハンドラーに対する共通の前処理)でcontextにリ
    クエストIDを注入しておく
    ○ [Python] aiohttpでリクエストスコープのコンテキスト情報を扱う
    ■ https://budougumi0617.github.io/2020/04/08/python-use-context-var-in-aiohttp/
    33
    Python(aiohttp)でContextを使う

    View Slide

  34. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● Middleware(ハンドラーに対する共通の前処理)でcontextにリ
    クエストIDを注入しておく
    34
    Python(aiohttp)でContextを使う

    View Slide

  35. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● ロギングやエラーレポート送信時にcontextからリクエストIDを
    取り出す
    35
    Python(aiohttp)でContextを使う

    View Slide

  36. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● アクセスログにもリクエストIDを付与する
    ○ [Python] aiohttpで独自形式のアクセスログを出力する
    ■ https://budougumi0617.github.io/2020/04/11/python-access-log-in-aiohttp/
    36
    Python(aiohttp)でContextを使う

    View Slide

  37. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc. 37
    リクエストIDでログ同士、エラーの関連性を可視化
    リクエストID生成
    with ID
    with ID
    with ID with ID
    with ID
    ● アプリケーションコードの変更のみでIDを付与するようにした
    with ID

    View Slide

  38. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● 通知されたエラーレポートのリクエストIDを確認する
    38
    ゆるふわ分散トレース実装後

    View Slide

  39. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ● KibanaやCloud Watch LogsでリクエストIDを検索する
    39
    ゆるふわ分散トレース実装後

    View Slide

  40. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc. 40
    ゆるふわ分散トレース実装後
    ● IDを検索するだけで関連ログが探せるようになった!
    Before After

    View Slide

  41. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc.
    ログやエラーの関連性を
    可視化できた
    kibanaやCWLでIDを検索するだけで
    関連ログが探せるようになった!
    41

    View Slide

  42. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc. 42
    ● 複数サービスでシステムを構成したときに生じる悩みを共有する
    ● 分散トレースについてざっくり知ってもらう
    ● インフラ構成の変更、追加予算なしで始める方法の紹介
    ● リクエストIDを付けるだけでも解析が便利になることを共有する
    今日のゴール

    View Slide

  43. © 2012-2019 BASE, Inc.
    © 2012-2020 BASE, Inc. 43
    ● 分散トレースをしたくなるときを説明
    ● 分散トレースの概要を説明
    ● GoやPythonでどうやってリクエストIDを引き回すか解説
    ● インフラ構成やランニングコストを変えずにログやエラーを追跡
    できるようになった
    ● 複数言語で類似処理を実装すると言語差異を感じられて楽しい
    まとめ

    View Slide