ひとことで言うと#
1つのリクエストが複数のマイクロサービスを通過する過程をトレースIDで紐づけて一気通貫で可視化する手法。どのサービスで何ミリ秒かかったか、どこでエラーが発生したかをフレームグラフのように確認できる。
押さえておきたい用語#
- Trace(トレース)
- 1つのリクエストの全体的な流れのこと。一意のTrace IDで識別され、複数のSpanで構成されるツリー構造を持つ。
- Span(スパン)
- Trace内の個々の処理単位のこと。サービスAの処理、サービスBへの呼び出しなど。開始時刻・終了時刻・ステータスを持ち、親子関係でツリーを形成する。
- コンテキスト伝搬(Context Propagation)
- トレース情報をサービス間で引き渡す仕組みのこと。HTTPヘッダー(W3C Trace Context等)やgRPCメタデータで伝搬し、分散した処理を1つのTraceに紐づける。
- テールサンプリング(Tail Sampling)
- トレース完了後にエラーや高レイテンシのリクエストを優先的に記録するサンプリング手法のこと。全量記録よりコスト効率が良く、問題のあるトレースを確実に残せる。
分散トレーシングの全体像#
こんな悩みに効く#
- APIのレスポンスが遅いが、どのサービスがボトルネックかわからない
- エラーが発生しているが、複数サービスにまたがっていて原因の切り分けに時間がかかる
- ログを各サービスごとに追いかけるのが限界になっている
基本の使い方#
分散トレーシングの3つの基本要素を把握する。
- Trace: 1つのリクエストの全体的な流れ。一意のTrace IDで識別される
- Span: Trace内の個々の処理単位。サービスAの処理、サービスBへの呼び出しなど
- Context Propagation: トレース情報をサービス間で引き渡す仕組み(HTTPヘッダーなどで伝搬)
ポイント: 1つのTraceは複数のSpanで構成されるツリー構造。親Spanが子Spanを呼び出す関係になる。
標準規格と実装ツールを選定する。
- OpenTelemetry: ベンダー中立のトレーシング標準。現在の事実上のスタンダード
- バックエンド: Jaeger、Zipkin、Grafana Tempo、Datadog APMなど
- 各サービスにOpenTelemetry SDKを組み込み、トレース情報をバックエンドに送信する
ポイント: OpenTelemetryを採用しておけば、バックエンドを後から自由に切り替えられる。
アプリケーションにトレーシングコードを組み込む。
- 自動計装: フレームワーク(Express、Spring Bootなど)のHTTPリクエストを自動でSpan化
- 手動計装: 重要なビジネスロジックにカスタムSpanを追加(例: DB問い合わせ、外部API呼び出し)
- コンテキスト伝搬: サービス間呼び出し時にTrace情報をヘッダーで引き渡す設定
ポイント: まず自動計装で全体を把握し、詳細が必要な箇所だけ手動計装を追加する。
全リクエストをトレースするか、一部だけにするかを決める。
- 全量トレース: すべてのリクエストを記録。データ量とコストが大きい
- 確率サンプリング: リクエストの一定割合(例: 10%)だけ記録
- テールサンプリング: エラーや高レイテンシのリクエストを優先的に記録
ポイント: テールサンプリングが最もコスト効率が良い。問題のあるトレースを確実に残せる。
具体例#
状況: ECサイトの注文APIのレスポンスタイムが平均800msから2秒に悪化。APIゲートウェイ→注文サービス→在庫サービス→決済サービスの4段階で、どこが原因かわからない。
トレース分析:
- Jaegerで遅延リクエストのTraceを検索
- フレームグラフを確認: APIゲートウェイ(50ms) → 注文サービス(100ms) → 在庫サービス(1,200ms) → 決済サービス(150ms)
- 在庫サービスのSpanを深掘り: DBクエリのSpanが1,100ms → インデックスが欠落していたSQLクエリを発見
対応: 在庫テーブルに適切なインデックスを追加。レスポンスタイムが2秒→600msに改善。分散トレーシングのおかげで10分で原因を特定できた。
Before: 全量トレースで月間50億Spanを記録。ストレージコストが月**$8,000**。しかし実際に調査に使うのは全Traceの0.1%以下。
テールサンプリング導入:
- OpenTelemetry CollectorにTail Sampling Processorを設定
- ルール: エラーTraceは100%保存、レイテンシp99超のTraceは100%保存、正常Traceは5%保存
After: 月間Span数が50億→8億(84%削減)。ストレージコストが$8,000→$1,200。障害調査に必要なTraceは100%残っているため、調査能力は低下せず。
状況: マイクロサービス12個で構成されるシステム。障害時はログをgrepして4〜5サービスのログを突き合わせるのに平均2時間かかっていた。
段階的導入:
- Week 1: 最もトラフィックの多いAPIゲートウェイと注文サービスに自動計装を導入
- Week 2-3: 残り10サービスにOpenTelemetry SDKを順次追加
- Week 4: DBクエリと外部API呼び出しに手動計装を追加
結果: 障害原因の特定時間が平均2時間→15分に短縮(87%改善)。「このリクエストがどのサービスをどの順序で通ったか」がワンクリックで可視化できるようになった。
やりがちな失敗パターン#
- 全量トレースでコストが爆発する — トラフィックが多い環境で全リクエストをトレースすると、ストレージとネットワークのコストが膨大になる。サンプリング戦略を必ず設定する
- コンテキスト伝搬の漏れ — 1つのサービスがTrace情報を伝搬しないと、そこでTraceが途切れる。全サービスでコンテキスト伝搬が正しく機能しているかを検証する
- Span数が多すぎて見づらくなる — すべての関数にSpanを追加すると、1つのTraceに何百ものSpanが並び分析が困難に。サービス境界とDB/外部API呼び出しに絞って計装する
- トレースデータを見る習慣がない — ツールを導入しただけで誰も使わない。障害対応のランブックに「まずTraceを確認」を明記し、チームの習慣にする
まとめ#
分散トレーシングはマイクロサービスの 「X線検査」。リクエストがどのサービスをどの順序で通過し、各段階でどれだけ時間がかかったかを可視化する。OpenTelemetryで計装し、テールサンプリングでコストを抑え、障害時に素早く原因を特定できる体制を整えよう。