Jaegerは、マイクロサービスのリクエストとデータフローを可視化する分散トレーシングシステムです。
Jaegerとは
マイクロサービスは複数のサービスを呼び出して1つの大きなリクエストを実現しています。そのため、サービス依存関係の把握やパフォーマンス遅延の原因特定などがとても難しくなります。この問題を解決するために、アプリケーションを監視する役割を持つ分散トレーシングシステムが生まれました。その1つがJaegerになります。
前回紹介したIstio自体にもトレーシング機能はありますが、Jaegerと組み合わせることで、より詳細なトレースや可視化・分析を行うことができます。
Jaegerでできること
フローの監視とトラブルシューティング
サービス間のフローをモニタリングすることができます。ユーザー体験が悪くなる前に問題を検出して解決するために役立ちます。
サービス依存関係の分析
サービスの依存関係とはアプリケーションを実行するために複数のコンポーネントに依存していることを指します。
パフォーマンスのボトルネック特定
コンポーネントごとにパフォーマンスを監視することで、アプリケーションを遅延させる原因箇所(ボトルネック)を特定することができます。
根本原因の分析
マイクロサービスでは、1つの問題が他の問題を引き起こす可能性があります。フローを監視することで、根本原因となっている問題を見つけることができます。
Jaegerの構成要素
分散トレーシングの主要な用語として以下の二つが挙げられます。
スパン
スパンは作業名、作業開始時間、作業期間を持つ論理的な作業単位を表します。因果関係をモデル化するためにスパンをネストして順序付けすることができます。
トレース
トレースはシステム内のデータや実行パスを表します。これは作業の有向非巡回グラフと考えることができます。
スパンとトレースについては以下の画像を参考にすると理解しやすいです。トレースとスパンの関係については、トレースはリクエストからレスポンスまでの一連の流れを表すスパンの集合で、スパンは1つのサービス内の処理のことを指します。トレースはフローを可視化することができるため、遅延やエラーがどこで発生しているかを理解することができます。スパンにはサービスの開始時間、終了時間、タグ、ログメッセージなどの情報が含まれるため、トレース内でのパフォーマンスの問題を特定するときに役立ちます。
ImageSource : https://www.jaegertracing.io/docs/1.48/architecture/
アーキテクチャ
まず、Jaeger CollectorはOpenTelemetryのTracing SDKからOpenTelemetry Protocol (OTLP)でトレースデータを受信します。それを直接ストレージに書き込み、トラフィックを処理します。処理したデータを用いてJaeger UIでトレーシングを行うことができます。
ImageSource : https://www.jaegertracing.io/docs/1.48/architecture/
デモ
ここでは簡単にJagerのGetting Startedを行ってみたいと思います。マイクロサービスのサンプルアプリケーションHotRODの分散トレーシングを行います。
動作環境
OS : WSL2 – Ubuntu 22.04.2 LTS
Docker Compose : Docker Compose version v2.18.1
Jaeger:v1.48
docker-compose経由で実行
はじめに、 https://github.com/jaegertracing/jaeger/blob/main/examples/hotrod/docker-compose.yml からdocker-compsoe.ymlをダウンロードします。
docker-compsoe.ymlの中身
version: '3.7'
services:
jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686"
- "4318:4318"
environment:
- LOG_LEVEL=debug
networks:
- jaeger-example
hotrod:
image: jaegertracing/example-hotrod:latest
# To run the latest trunk build, find the tag at Docker Hub and use the line below
# https://hub.docker.com/r/jaegertracing/example-hotrod-snapshot/tags
#image: jaegertracing/example-hotrod-snapshot:0ab8f2fcb12ff0d10830c1ee3bb52b745522db6c
ports:
- "8080:8080"
- "8083:8083"
# TODO remove "--otel-exporter=otlp" after 1.49 release
command: ["all", "--otel-exporter=otlp"]
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4318
networks:
- jaeger-example
depends_on:
- jaeger
networks:
jaeger-example:
docker-compose up でJaegerUIとHotRODデモを実行します。次に、http://localhost:16686でJaeger UIにアクセスし、http://localhost:8080でHotRODアプリにアクセスします。
他の実行方法もあります。https://github.com/uber/jaeger/tree/main/examples/hotrod
JaegerUIとHotRODを表示させることができました。
HotRODはライドシェアアプリで、4つのボタンのいずれかをクリックすると車が顧客の元に到着し、おそらく車を受け取ります。リクエストが送られると、車のナンバープレートと到着予定時刻を表示します。詳しくはこちら
HotRODでリクエストを送ってみます。
JaegerUIに移って、System ArchitectureタブからDAGを表示します。
アプリケーションのアーキテクチャを示してくれます。少し表示の都合で文字が被ってしまっていますが、4つのマイクロサービスと2つのデータベースで構成されています。呼び出しの回数も表示されています。routeサービスとredisの呼び出し回数が多いこともわかります。
次にデータの流れを見てみます。Searchタブに移動して、serviceドロップダウンにはルートサービスであるfrontendを設定してFind Tracesボタンをクリックします。するとトレース結果の一覧が表示されます。
トレースのタイトルをクリックすると詳細が表示されます。
アプリケーションがリクエストをどのように処理するかを確認することができます。
driverサービスがredisに対して一連の呼び出しを行っています。一部の表示は感嘆符表示がされており、エラーが起きていることがわかります。その後、frontendサービスはrouteサービスに一連のHTTP GETリクエストを実行しています。このように、タイムラインビューではエラーが発生している個所や並列処理されている箇所、実行時間のボトルネックになっている箇所などを簡単に発見することができます。
まとめ
Jaegerはマイクロサービスのリクエストとデータフローを可視化する分散トレーシングシステムです。トレーシングを行うことでアーキテクチャや処理フローを視覚化することができます。このように、複雑なサービスの依存関係やパフォーマンスのボトルネック、根本原因の分析を行う手助けをしてくれます。