Jaegerはトレーシングを行うツールなので、まずは分散システムにおけるトレーシングの意味を押さえると理解しやすくなります。複数のマイクロサービスが連携して動作する場合、それぞれのコンポーネントをまとめ上げ、常にやり取りを維持するのは大きな課題です。
モノリシックアーキテクチャは要素が少ないのでシンプルですが、マイクロサービスや分散システムでは、コンポーネントが複数のサービス間をどのように流れるかを常に把握する必要があります。
分散トレーシングは、複数のサービスにまたがるデータを集中管理できる仕組みです。別の言い方をすれば、マイクロサービスの中で発生するあらゆるイベントを可視化することとも言えます。
重要なデータやその流れを追跡することで、分散トレーシングは最適化やデバッグに大きく役立ちます。
ほとんどの場合、サービスメッシュの一部として機能し、マイクロサービス管理には欠かせない存在です。Jaegerがリクエストの流れを追いかけられるのは、この分散トレーシングを用いているためです。さらに、遅延の減少や根本原因の追究、そして分散トランザクションの監視を手助けします。
一般的に、Jaegerはマイクロサービスの監視やトラブルシューティングに広く使われる分散トレーシングソリューションです。複数のマイクロサービスで起こるイベントを視覚的にわかりやすく示してくれます。Jaegerトレーシングとも呼ばれ、リクエストが通る流れを追跡する点が特徴です。
マイクロサービスの開発要素としても重要です。マイクロサービスには独立したRESTful APIやロジック、データベースを持つ小さなアプリが多数存在し、それらはリクエストとレスポンスでやり取りします。
Jaegerはトレースやログによって、全体を整理します。Jaegerが担う主な役割は以下のとおりです:
Instrumentationはトレースやログ、メトリクスなどのテレメトリーデータを生成するためのコンポーネントです。アプリのコードによってテレメトリーデータが作られ、これを利用してエラーの調査などを行えます。
多くの場合、SDKやエージェント、クライアントライブラリなどがInstrumentationに活用されます。Jaegerの場合はOpenTracing APIをベースとしたクライアントライブラリが使われます。
以前はOpenTracingが単独で機能していましたが、その後OpenTelemetryと統合されました。JaegerはJava、Go、C++、Node.js、C#といった複数言語向けのクライアントライブラリを提供しています。Instrumentationが完了すると、サービスは受信するトランザクションにスパンを生成し始めます。
分散トレーシングを利用すると、Jaegerの基本UIはさらにわかりやすい可視化を実現します。
次のコンポーネントであるData Pipelineは、さまざまな形式のデータを受け取るのに大いに役立ちます。サービスがトレースデータを収集すると、そのデータは可視化のためにバックエンドストレージへ直接送られます。しかし、その過程でデータが監視されないとトラブルが起きる可能性があります。
この段階でJaegerはデータパイプラインを活用し、データのバッファリングやバッチ処理、キューイング、インデックス付け、操作などをサポートします。
Jaegerはテスト用にシンプルなメモリ上のストレージを使うことがありますが、実際にはCassandraやElasticSearchなどが代表的なトレースストレージとして利用されます。
サンプリングはJaegerおよびそのライブラリで重要な要素で、トレースの0.1%などをサンプリングします。Jaegerクライアントはサンプリング戦略を自由に取得・変更でき、Constサンプラや確率的サンプラ、opentracing.jaeger.const-sampler.decision = true | false、レート制限サンプラなど、さまざまな方法があります。
Jaegerサンプリングを理解する際には、実行場所が2つあることを知ると良いでしょう。
詳しく見ていきます。
クライアントコードやSDKレベルで実行されるサンプリングは、ヘッドベースサンプリングとも呼ばれ、4つのモードがあります。
Remote(1つ目 - デフォルト): Jaegerクライアントへ「サンプリングがJaegerのバックエンドから渡される」ことを伝え、次のアクションを判断させます。
Constant: すべてのトレースを受け入れるか、すべてを棄却するかを決めるモードです。すべてを受け入れる場合は1、まったく受け入れない場合は0と示されます。
Rate Limiting: 1秒あたりにサンプリングできるトレースの上限を決めます。
Probabilistic: もっとも適切な割合でトレースをサンプリングするためのモードです。
こちらは2つのモードをサポートし、テイルベースサンプリングとも呼ばれます。
1つ目はファイルサンプリングで、Collectorに設定ファイルのパスを指定する方法です。設定ファイルには、サービス別・オペレーション別のサンプリング設定が含まれています。
2つ目はアダプティブサンプリングで、アダプティブサンプラをベースにしています。これは複数のサンプリング関数を組み合わせた複合サンプラです。
このレベルのサンプリングはJaeger Collectorで行われます。
たとえば、APIなど複数のエンドポイントを持つ場合、オペレーション単位のサンプリング判断が可能です。
また、サービス単位のパラメータからサンプリングのしきい値を決定するのにも役立ちます。パラメータはJaegerのバックエンドからRemote Samplerを使って取得することもできます。
Collectorは静的なサンプリング戦略を使ってトレースを初期化します。このとき--samplingおよびstrategies-fileオプションを使います。
最近のOpenTelemetry発表によりOpenCensusとOpenTracingの統合が決定し、Jaegerコミュニティは大きな変化を迎えました。統合後もJaegerはOpenTracingを用いていますが、これはどういうことなのでしょうか。
まず、JaegerトレーシングがOpenTracing仕様と密接に関わっている点を理解ください。いくつかの問題から、Jaegerの人気はゆるやかに下がっています。既存のJaegerクライアントはOpenTelemetry SDKを推奨しておらず、言語の互換性を選べたり、Jaegerエクスポーターを使うことが可能です。
Jaegerエクスポーターを用いると、Jaeger分散トレーシング内のスパンが作られ、それを扱いやすい形式に変換します。そうしたスパンはストレージとJaeger Collector間をスムーズに行き来できます。
現時点ではOpenTelemetryがJaegerトレーシングCollectorを完全に置き換えるとは言い切れませんが、将来的にその可能性はあります。というのも、Jaegerは以前ほどの人気を保っていないのが現状だからです。
OpenTelemetryはJaegerの弱点を埋めて、充実した単一の標準を提供するため、開発者コミュニティから注目されています。OpenTracingやOpenCensusの後方互換性を保ちつつ、不要な機能は増やさない点も評価ポイントです。一元的なオブザーバビリティ基盤として動作し、Jaegerのようなクラウドネイティブツールよりシンプルな運用が可能と見られています。
Jaegerは幅広く使えますが、完全なトラブルシューティングにはトレースだけでなく各種メトリクスも必要になります。例えば、レスポンスタイムやCPU使用量、エラーレートなどのメトリクスです。これらはアプリ全体の状況をより的確に把握するうえで重要です。
ところが、Jaegerはこれらのメトリクスをキャッチできないため、いくつかの不足が生じます。例えば:
トレースだけしか取得できないため、メトリクスやログ管理用の別ツールが必要となり、管理が煩雑になります。
Jaegerに起因する課題を補うには、以下のような代替ツールを検討できます:
Jaegerはマイクロサービスや分散システム開発において、データやイベントを追跡するうえで有用な手段です。しかし、メトリクスを追跡できないため、トラブルシューティングや管理面で不十分な点があります。
常に他のオプションも検討できます。開発の目標を明確にし、ロギングやメトリクス追跡を含む安心感のある仕組みを整えて、より強固な連携を実現しましょう。
最新情報を購読