TT Lab
はじめる
学ぶ 学習パス コース

マイクロサービスアーキテクチャ

相関IDの伝播を検証する

TT Labで続きを見る

目標

W3Cのtraceparentを手で作って、3段のサービスチェーンに伝播し、ログをトレースIDで結合して、リクエスト1つの経路を復元します。

なぜ重要なのか

分散トレーシングを「3つ目のシグナルだから必要」と説明すると、導入に失敗します。正確にどんな質問に答えるのかを知っておく必要があります。10個のサービスのp99がすべて正常なのに、ユーザーの画面は2秒かかる状況では、メトリクスは原理的に無力です。集計値なので、個別のリクエストの経路を復元できないからです。1つのリクエストで、4msのクエリが340回実行されるN+1問題も、メトリクスには絶対に見えません。個別のクエリが速いからです。このラボでは、SDKなしで、ヘッダーの3つの断片だけでその経路を復元してみることで、後でOpenTelemetryを組み込むときに、何が実際に起きているのかを知った上で組み込めるようにします。

ステップ

  1. /opt/app/chain.pyで、ゲートウェイ(8120)、注文(8121)、在庫(8122)の3つのサービスを起動してください。GET http://127.0.0.1:8120/orderが200を返します。
  2. /root/trace/gen.pyでtraceparentを作成して、/root/trace/tp.txtに1行で保存してください。00-<32hex>-<16hex>-01の形式でなければなりません。
  3. そのヘッダーでゲートウェイを呼び出してください。3つのサービスがそれぞれ/root/trace/svc-<이름>.logにtrace_id=<값>を残し(プレースホルダーは名前と値です)、3つの値がすべて同じでなければなりません。
  4. 各ログに、span_id=<16hex>とparent_span_id=<16hex>も残してください。3つのサービスのspan_idは、互いに異なっていなければなりません。
  5. /root/trace/join.shで、3つのログから同じtrace_idの行だけを取り出して、/root/trace/joined.logに時刻順に3行残してください。
  6. /opt/app/brokenchain.shを実行すると、8123/8124/8125に2つ目のチェーンが起動し、そのうち1つのサービスがヘッダーを捨てます。各サービスは、/root/trace/broken-<이름>.logにsvc=<이름> in_trace=<값> out_trace=<값>を残します(プレースホルダーは名前と値です)。入ってきたトレースIDと出ていったトレースIDが異なるサービスを見つけて、その名前を/root/trace/broken.txtに1行で書いてください。
  7. /root/trace/selftime.txtに、slowest=<서비스명> total_ms=<정수>とself_ms=<정수>の2行を書いてください(プレースホルダーはサービス名と整数です)。selfは、全体から子のスパンを引いた値です。

参考

3段のチェーンサービスを起動する

/opt/app/chain.pyで、ゲートウェイ(8120)、注文(8121)、在庫(8122)の3つのサービスを起動してください。GET http://127.0.0.1:8120/orderが200を返します。

/opt/app/chain.pyは、引数として受け取ったポートで起動し、次のホップのアドレスを環境変数で受け取ります。ゲートウェイ、注文、在庫の順に、3つを起動してください。

traceparentヘッダーを作る

/root/trace/gen.pyでtraceparentを作成して、/root/trace/tp.txtに1行で保存してください。00-<32hex>-<16hex>-01の形式でなければなりません。

バージョン2桁、トレースID32桁、スパンID16桁、フラグ2桁を、ハイフンでつなぎます。すべて小文字の16進数でなければなりません。

末端まで同じトレースIDを渡す

そのヘッダーでゲートウェイを呼び出してください。3つのサービスがそれぞれ/root/trace/svc-<이름>.logにtrace_id=<값>を残し(プレースホルダーは名前と値です)、3つの値がすべて同じでなければなりません。

各サービスが、受け取ったヘッダーからトレースIDだけをそのまま渡し、自分のログに残すようにしてください。

ホップごとにスパンIDを変える

各ログに、span_id=<16hex>とparent_span_id=<16hex>も残してください。3つのサービスのspan_idは、互いに異なっていなければなりません。

親スパンIDの位置には、自分のスパンIDを入れて送ります。3つのログのスパンIDがすべて異なっていれば正常です。

3つのログをトレースIDで結合する

/root/trace/join.shで、3つのログから同じtrace_idの行だけを取り出して、/root/trace/joined.logに時刻順に3行残してください。

サービスごとのログファイルを、トレースIDでふるい分けて、時刻順につなげます。結合の結果が、ちょうど3行でなければなりません。

伝播が途切れたサービスを見つける

/opt/app/brokenchain.shを実行すると、8123/8124/8125に2つ目のチェーンが起動し、そのうち1つのサービスがヘッダーを捨てます。各サービスは、/root/trace/broken-<이름>.logにsvc=<이름> in_trace=<값> out_trace=<값>を残します(プレースホルダーは名前と値です)。入ってきたトレースIDと出ていったトレースIDが異なるサービスを見つけて、その名前を/root/trace/broken.txtに1行で書いてください。

わざとヘッダーを捨てるサービスが1つあります。トレースIDが変わる地点を見つければ済みます。

自己時間を計算する

/root/trace/selftime.txtに、slowest=<서비스명> total_ms=<정수>とself_ms=<정수>の2行を書いてください(プレースホルダーはサービス名と整数です)。selfは、全体から子のスパンを引いた値です。

全体の継続時間から、子スパンの時間を引きます。最も遅い区間と、自己時間が大きい場所は、異なることがあります。