【入門編】 分散トレーシング(OpenTelemetry)によるリクエスト追跡 – Web APIアーキテクチャ・データ連携実践ガイド

こんにちは!ネットワークプロトコルスペシャリストの私です。

日頃からルーターの向こう側でパケットが跳ね回る様子や、APIの海をリクエストが旅する姿に思いを馳せているのですが……皆さんは、マイクロサービスという言葉を聞いたとき、どんな景色を想像するでしょうか?

「ユーザーからの注文を受ける係」「在庫を確認する係」「決済を行う係」など、小さな専門家たちがチームを組んで、まるで一つの巨大なシステムのように動く現代のWebアプリケーション。美しく設計されたREST APIたちが、日夜せっせとデータをやり取りしていますよね。

ただ、この「チームプレイ」が少し曲者(くせもの)なんです。
ある日、ユーザーから「なんか決済ボタンを押してから画面が出るまですごく遅いんだけど!」というクレームが入ったとします。さあ大変。この遅延、一体どのサービスのせいで起きているのでしょうか?
注文サービス?それとも在庫?あるいは決済?
海千山千のエンジニアでも、各サービスがバラバラに出しているログ(航海日誌)を突き合わせて犯人を探すのは、暗闇で針を探すようなもの……。

そこで登場するのが、今回の主役である「分散トレーシング(OpenTelemetry)」です。
今回は、小難しいパケットの仕組みや英語のヘッダー名はいったん脇に置いて、身近な「郵便配達」の仕組みに例えながら、一歩ずつ優しく紐解いていきましょう!

—

1. 郵便配達で例える「分散トレーシング」の世界

想像してみてください。あなたは今、ネットショッピングで欲しかったスニーカーを注文しました。
この注文を完了させるために、舞台裏では次のようなドラマが起きています。

1. 注文サービス(Aさん)が注文を受け付けます。「お、スニーカーの注文だね!」
2. Aさんは、在庫があるか調べるために、在庫サービス(Bさん)に内線電話をかけます。「在庫ある?」
3. Bさんは倉庫を調べて「あるよ!」と返答します。
4. 次にAさんは、お金を払ってもらうために、決済サービス(Cさん)に書類を回します。「決済よろしく!」
5. Cさんがクレカの処理をして「OK!」と返します。
6. すべてが完了し、Aさんはユーザーに「注文完了しました!」と笑顔で伝えます。

さて、ここで問題です。
この一連の流れ全体で「3秒」かかったとします。でも、どこでモタモタしていたのか、このままだと誰も分かりませんよね。Bさんの在庫調べが遅かったのか、それともCさんの決済処理が重かったのか……。

ここで「荷物追跡番号(追跡伝票)」の登場です!

ネット通販で買い物をすると、ヤマト運輸や日本郵便の「お荷物追跡番号」が発行されますよね。あの番号を段ボールにペタッと貼っておけば、荷物が「今どこにあって、どの配送センターを何時に通過したのか」がスマホで一目瞭然になります。

分散トレーシングの仕組みも、これと全く同じです。
ユーザーからの最初のリクエストがシステムに入ってきた瞬間、システム全体で共有される「一生モノの旅券番号(Trace ID)」を発行します。そして、サービスAからサービスB、サービスCへとバトンタッチ(リクエストの転送)をする際、この「Trace ID」をこっそり荷物に添えて一緒に送るのです。

これさえあれば、「Trace ID: 12345」の荷物が通った足跡をタイムライン形式で綺麗に可視化し、「おや、在庫サービス(Bさん)のところで2.5秒も足止めを食らっているぞ!」と一瞬でボトネネックを特定できるようになります。これが、分散トレーシングがもたらす魔法の可視化なのです。

—

2. OpenTelemetryってなんだろう?

「なるほど、荷物に追跡番号を貼ればいいのね! でも、それって各社が勝手にバラバラのやり方で作っちゃったら、意味がなくなっちゃうのでは?」

その通り!非常に鋭い着眼点です。
もしサービスAが「追跡番号」という名前で渡し、サービスBが「Tracking-No」という名前で受け取ろうとしたら、言葉が通じなくて荷物が行方不明になってしまいますよね。

そこで世界中のエンジニアが立ち上がり、「みんなでこの共通の規格(プロトコル)を使おうぜ!」と定めた標準規格が、OpenTelemetry(オープンテレメトリー、通称OTel)です。

OpenTelemetryは、アプリが発する「ログ」「メトリクス(数値データ)」「トレース(足跡)」という3大お宝データを、綺麗に収集・統一するための業界標準の仕組みです。これを使えば、言語やクラウドの垣根を越えて、世界共通の「追跡ルール」でシステムを繋ぐことができるようになります。

—

3. 実装のイメージを掴もう(Pythonのコード例)

「概念はわかったけれど、実際のコードではどう書くの?」
安心してください。難しく考えず、HTTPリクエストを送る際に「Trace ID(追跡番号)」をそっと手紙(HTTPヘッダー)に忍ばせるイメージを見てみましょう。

以下のPythonコード(Flaskとrequestsライブラリを使用)は、OpenTelemetryの概念をとてもシンプルに表現したものです。

import requests
from flask import Flask, request

app = Flask(__name__)


# 注文サービス(Aさん)のエンドポイント
@app.route("/order", methods=["POST"])
def create_order():
    # 1. ユーザーからのリクエストを受け取る
    print("-> 注文を受け付けました!")

    # 2. 外部の決済サービス(Cさん)へリクエストを転送する準備
    # OpenTelemetryが自動的に現在の「Trace ID」をヘッダーに仕込んでくれますが、
    # ここではイメージとして、専用の追跡ヘッダーを明示的に付与してみます。
    trace_id = request.headers.get("X-Cloud-Trace-Context", "unknown-trace-id")
    headers = {"X-Cloud-Trace-Context": trace_id}

    print(f"-> 決済サービスへ荷物を送ります。現在のTrace ID: {trace_id}")

    # 3. 決済サービスへHTTPリクエストを送信
    response = requests.post(
        "http://payment-service/pay", headers=headers, json={"amount": 1000}
    )

    return "注文完了!", 200


if __name__ == "__main__":
    app.run(port=8080)

このコードのポイントは、X-Cloud-Trace-Context といったHTTPヘッダー(手紙の封筒の宛名書きのようなもの)に、現在の旅のIDを詰め込んで次のサービスへパスしている点です。
実際のOpenTelemetryのライブラリ(SDK)を使うと、このヘッダーの伝播や、各処理にかかった時間の計測(スパンの作成)を、人間が手動で書かなくても自動でやってくれるようになります。すごく便利ですよね!

—

4. インフラ・ネットワークエンジニアとしての視点

さて、私たちインフラやネットワークの領域に身を置く者からすると、この分散トレーシングは「アプリケーション層のパケットキャプチャ」のような側面を持っています。

昔は、ルーターやファイアウォールの向こう側でパケットがどこをどう流れているかを追うために、tcpdump や Wireshark を開いてパケットの海を睨みつけていました。
しかし、現代のWebアプリケーションは通信の大部分が暗号化(HTTPS)され、クラウドの内部ロードバランサーやコンテナのネットワーク(KubernetesのPod間通信など)を複雑に経由するため、ネットワーク層のパケットを見るだけでは「どのAPIが遅いのか」を突き詰めるのが難しくなっています。

だからこそ、アプリケーションの最上流から最下流までをひとつの「Trace ID」で串刺しにし、ネットワークのトンネルの向こう側で起きている処理の遅延を可視化する分散トレーシングが、現代のインフラ運用において必須のインフラストラクチャとなっているのです。

—

まとめ:一歩ずつ、可視化の楽しさを知ろう

今回は、分散トレーシング(OpenTelemetry)について、郵便配達や荷物の追跡番号に例えて解説しました。

  • マイクロサービスの世界では、1つのリクエストが複数のサービスを旅する。
  • どこで遅延やエラーが起きているか分からないため、共通の「Trace ID(追跡番号)」を付与する。
  • その標準化ルールが「OpenTelemetry」である。
  • アプリのコードやHTTPヘッダーを通じて、旅の足跡が綺麗に繋がっていく。

「なんだか、アプリとインフラの境界線がだんだん面白くなってきたぞ……!」と感じていただけたなら、今回の記事は大成功です。
まずはご自身のローカル環境や小さなサンドボックス環境で、トレースデータが画面(JaegerやZipkinなどの可視化ツール)にニョキニョキと表示される感動をぜひ味わってみてください。

それでは、また次回のプロトコル探訪でお会いしましょう!

コメント

タイトルとURLをコピーしました