分散トレーシング
マイクロサービスをまたぐ1リクエストの流れを、区間ごとに記録して可視化する手法です。トレースとスパンで「どこで遅い・失敗したか」を特定し、OpenTelemetry で標準的に計測します。
- 1.分散トレーシングは、複数サービスを横断する1リクエストの経路を所要時間つきで追跡し、ボトルネックや失敗箇所を特定する手法。
- 2.トレース=1リクエスト全体、スパン=その中の各処理区間。trace_id を伝播させて span をつなぐのが要。
- 3.OpenTelemetry が計測の事実上の標準。SDK で span を出し、Jaeger / Tempo などのバックエンドで可視化する。
分散トレーシングとは
分散トレーシング(Distributed Tracing) は、1本のリクエストが複数のサービスを通っていく経路全体を、所要時間つきで記録・可視化する 手法です。注文1件が「APIゲートウェイ → 認証 → 在庫 → 決済 → 通知」と渡り歩くようなマイクロサービス構成で、どこで時間がかかったのか・どこで失敗したのか を一目で追えるようにします。
モノリス(1プロセス)なら、スタックトレースを見れば処理の流れは分かりました。ところがサービスがネットワーク越しに分かれると、「遅い」と言われても どのサービスのどの処理が犯人か が分かりません。各サービスのログを別々に grep して時刻で突き合わせる作業は、サービスが増えるほど破綻します。分散トレーシングはこの「横断の見えなさ」を解決します。
トレースとスパン
分散トレーシングの中核となる2つの概念が トレース と スパン です。
- スパン(Span):1つの処理区間 を表す単位。「在庫サービスでDBに問い合わせた」のような作業1つに対応し、開始時刻・終了時刻・名前・属性 を持ちます。
- トレース(Trace):1リクエスト全体 を表すもので、複数のスパンを 親子関係(ツリー) でつないだ集合です。
スパンは入れ子になります。親スパン(例:「決済処理」全体)の中に、子スパン(「カード会社API呼び出し」「DB更新」)がぶら下がる、という構造です。これにより「決済全体で2.4秒、うちカード会社APIが2.3秒」のように 時間の内訳 が見えます。
| 用語 | 表すもの | 持つ情報の例 |
|---|---|---|
| トレース | リクエスト1本の全経路 | trace_id、全スパンの集合 |
| スパン | 経路内の1処理区間 | span_id、名前、開始/終了時刻、属性 |
| 親子関係 | スパン間の呼び出し構造 | parent_span_id(どのスパンから呼ばれたか) |
トレースは多くのツールで「ウォーターフォール(滝)図」として表示されます。横軸が時間、各スパンが横棒で、長い棒・ずれて始まる棒が遅延の手がかり。視覚的に「ここが詰まっている」がすぐ分かるのが、ログの羅列との決定的な差です。
コンテキスト伝播:span をつなぐ仕組み
分散トレーシングの肝は コンテキスト伝播(Context Propagation) です。サービスをまたいでも同じトレースだと認識させるには、trace_id を後続のサービスへ渡し続ける 必要があります。
仕組みはシンプルで、サービスAがサービスBを呼ぶとき、HTTPヘッダに識別子を載せます。標準は W3C Trace Context(traceparent ヘッダ)です。
# サービス間の HTTP リクエストに付く Trace Context ヘッダの例
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
# │ └─ trace_id(リクエスト全体で共通) └─ parent span_id
# └─ バージョン
各サービスは、受け取った trace_id を引き継いで自分のスパンを作り、さらに下流へ渡します。これが切れると そこでトレースが分断 され、「経路の途中から先が真っ暗」になります。伝播の維持が、使える分散トレーシングの生命線です。
非同期メッセージ(キュー)やバッチ、自前のHTTPクライアント経由だと、ヘッダの引き継ぎが抜けてトレースが途切れがちです。「途中までしか追えない」ときは、たいてい どこかのサービス境界でコンテキストを渡し損ねて います。境界ごとに伝播されているかを確認しましょう。
OpenTelemetry:計測の標準
かつてはツールごとに計測方法がバラバラ(Zipkin 形式、Jaeger 形式…)で、乗り換えのたびにコードを書き直す必要がありました。これを統一したのが OpenTelemetry(OTel) です。CNCF のプロジェクトで、トレース・メトリクス・ログを共通の規格で収集する 事実上の標準になっています。
役割分担を整理すると次のようになります。
| 構成要素 | 役割 |
|---|---|
| SDK / API | アプリ内でスパンを生成・属性付与する(計測コード) |
| 自動計測(instrumentation) | フレームワークやHTTPクライアントに自動でスパンを差し込む |
| Collector | 送られた信号を受け取り、加工・中継してバックエンドへ送る |
| バックエンド | 保存・可視化する(Jaeger / Tempo / 各種SaaS など) |
ポイントは、計測(OTel)と保存・可視化(バックエンド)が分離 されていること。アプリ側を OpenTelemetry で計測しておけば、可視化ツールを Jaeger から別の製品に変えても アプリのコードはそのまま です。ベンダーロックインを避けられるのが大きな利点です。
サンプリング:全部は採らない
すべてのリクエストのトレースを保存すると、量もコストも膨大になります。そこで サンプリング(標本抽出) で記録するトレースを間引きます。
- ヘッドサンプリング:リクエストの入口で「採る/採らない」を確率的に決める(例:1%だけ保存)。シンプルだが、保存対象を選んだ後に起きたエラー を取りこぼす。
- テールサンプリング:トレースが出揃ってから判断する。「エラーが出た」「異常に遅い」トレースだけ残す といった賢い選別ができるが、一旦全スパンを集める分だけ仕組みが重い。
「正常で速いリクエストは間引き、遅い・失敗したものは確実に残す」のが理想で、テールサンプリングはそれに近づけます。
トレースはオブザーバビリティ(/devops/observability/)の3本柱の1つで、答える問いは 「どこで遅い/失敗したか」。メトリクスで異変に気づき、トレースで犯人のサービス・区間を絞り、ログでその詳細を読む——trace_id を全ログに載せておくと、この横断が一気通貫でつながります。
まとめ
- 分散トレーシングは 複数サービスをまたぐ1リクエストの経路を所要時間つきで可視化 し、ボトルネックや失敗箇所を特定する手法。
- トレース=全経路、スパン=各処理区間。
trace_idを伝播させて span をつなぐのが要で、伝播が切れると追えなくなる。 - OpenTelemetry が計測の標準。計測と可視化が分離され、バックエンド(Jaeger / Tempo 等)を差し替えてもコードは不変。
- サンプリング で量とコストを調整しつつ、遅い・失敗したトレースは確実に残すのがコツ。
DevOps/インフラ Article
分散トレーシングを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
分散トレース
比較で見る軸
難易度: intermediate / カテゴリ: DevOps/インフラ / タグ数: 4
導入後に効く点
トレース=1リクエスト全体、スパン=その中の各処理区間。trace_id を伝播させて span をつなぐのが要。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- intermediate
- カテゴリ
- DevOps/インフラ
- タグ数
- 4
判断チェックリスト
- 自社の用途が「分散トレース / OpenTelemetry」に近いか確認する。
- 強みである「分散トレーシングは、複数サービスを横断する1リクエストの経路を所要時間つきで追跡し、ボトルネックや失敗箇所を特定する手法。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。