分散トレース開発ガイドライン

GitLabは分散トレースのためのインストゥルメントです。GitLabの分散トレースは、現在実験的なものとみなされています。GitLab.comではまだ大規模なテストが行われていないからです。

Open Tracingによると:

分散トレースは分散リクエストトレースとも呼ばれ、アプリケーション、特にマイクロサービスアーキテクチャを使用して構築されたアプリケーションのプロファイリングとモニタリングに使用される手法です。分散トレースは、どこで障害が発生し、何がパフォーマンス低下の原因なのかを突き止めるのに役立ちます。

分散トレースは、GitLabアプリケーションの異なるコンポーネントを通過するリクエストのライフサイクルを理解するのに特に役立ちます。現在のところ、Workhorse、Rails、Sidekiq、Gitalyがトレース・インストゥルメンテーションをサポートしています。

分散トレースは無効にすると最小限のオーバーヘッドしか追加しませんが、有効にするとわずかなオーバーヘッドしか課しません。このため、本番環境でのイシュー、特にパフォーマンスの問題を診断するのに役立ちます。

サービスによってディストリビューショントレースのサポートレベルは異なります。カスタムインスツルメンテーションコードは、最も一般的なライブラリのための事前構築されたインスツルメンテーションに加えて、アプリケーション層に追加されなければなりません。

サービス固有の情報については

相関IDを使ったディストリビューションリクエストの調査

GitLabアプリケーションはリクエストの様々なコンポーネント間で相関IDを渡します。相関IDは、異なるGitLabサブシステム(例えば、RailsやWorkhorse)間で一つのリクエストを相関させるために使われる、一つのリクエストに固有のトークンです。相関 ID はログ出力に含まれるため、エンジニアは相関 ID を使って異なるサブシステムからのログを相関させ、リクエストのシステム経由のエンドツーエンドのパスをよりよく理解することができます。要求がプロセス境界を通過するとき、相関 ID は送信要求に注入されます。これにより、相関 ID がダウンストリームの各サブシステムに伝搬されます。

相関IDは通常、特定のWebリクエストに応じてRailsアプリケーション内で生成されます。ユーザー向けシステムの中には、ユーザーリクエストに応答して相関IDを生成しないものもあります (たとえば、SSH経由のGitプッシュなど)。

相関IDを扱うための開発者ガイドライン

新しいシステムにトレースをインテグレーションする際、開発者は相関IDについて特定の仮定をすることを避けるべきです。以下のガイドラインはGitLabのすべてのサブシステムに適用されます:

  • 相関 ID は常にオプションです。
    • トレース以外の機能が、アップストリームシステムからの相関IDの存在に依存することはありません。
  • 相関IDは常にフリーテキストです。
    • 相関 ID は、コンテキスト (ユーザー名や IP アドレスなど) を渡すために使用しないでください。
    • 相関 ID を_解析_したり、他の方法(例えば、分割など)で操作したりしないでください。

LabKitライブラリは、Goプログラミング言語でGitLab相関IDを扱うための標準化されたインターフェイスを提供します。LabKitは、Go以外のGitLabサブシステムでトレースや相関IDを扱う開発者のための参照実装として使用できます。

ディストリビューション・トレーシングの有効化

GitLab はGITLAB_TRACING 環境変数を使って分散トレースを設定します。すべてのコンポーネント(例えばWorkhorseやRailsなど)で同じ設定が使われます。

GITLAB_TRACING が設定されていない場合、アプリケーションはインスツルメンテーションされません。つまり、オーバーヘッドはまったくありません。

GITLAB_TRACING を有効にするには、URLのような形式で、有効な_“configuration-string “_値を設定しなければなりません:

GITLAB_TRACING=opentracing://<driver>?<param_name>=<param_value>&<param_name_2>=<param_value_2>

この例では、次のような仮想的な値があります:

  • driverこのようなイェーガーのドライバー。
  • param_name param_value: ドライバ固有の設定値です。Jaegerの設定パラメータは、このドキュメントでさらに詳しく説明しています。複数の値は URL のように& で区切ってください。

GitLab Railsは、リクエストの詳細なビューを提供する、一般的なタイプのオペレーションに対して実装済みのインスツルメンテーションを提供します。しかし、詳細な情報には代償が伴います。結果として得られるトレースは長く、処理が難しく、根本的な問題を特定するのが難しくなります。この問題にアドレスするために、いくつかのインスツルメンテーションは デフォルトでは無効になっています。無効になっているインスツルメンテーションを有効にするには、 以下の環境変数を設定してください:

  • GITLAB_TRACING_TRACK_CACHESキャッシュの読み取り、書き込み、削除などのオペレーションを追跡できるようにします。
  • GITLAB_TRACING_TRACK_REDIS: Redisオペレーションを追跡できるようにします。ほとんどのRedisオペレーションはキャッシュのためのものです。

GitLab開発キットでJaegerを使う

GitLabが最初にサポートするトレース実装はJaegerで、GitLab Development KitはJaegerを使ったディストリビューショントレースをすぐにサポートします。GDKは自動的にGITLAB_TRACING 環境変数を追加してサービスを追加します。

gdk.yml ファイルを編集して以下の設定を追加することで、Jaeger用にGDKを設定します:

tracer:
  build_tags: tracer_static tracer_static_jaeger
  jaeger:
    enabled: true
    listen_address: 127.0.0.1
    version: 1.43.0

gdk.yml ファイルを修正した後、gdk reconfigure コマンドを実行して GDK を再設定してください。これにより、GDKが適切に設定され、使用できるようになります。

上記の設定では、Goで書かれたサービスを初めて再構築するときに、tracer_statictracer_static_jaeger ビルドタグを設定します。その後に変更を加えた場合は、これらのビルドタグを使用して再構築する必要があります。次のいずれかを実行できます:

  • これらのビルド タグをデフォルトのビルド タグ セットに追加します。
  • 手動でビルドコマンドに追加します。例えば、Gitalyはビルドタグの追加をサポートしています。make all WITH_BUNDLED_GIT=YesPlease BUILD_TAGS="tracer_static tracer_static_jaeger".

再設定後、Jaegerダッシュボードはhttp://localhost:16686 。GDK環境からトレースにアクセスするもう1つの方法は、パフォーマンスバーです。これはブラウザウィンドウでp b と入力すると表示されます。

パフォーマンス・バーを有効にしたら、パフォーマンス・バーでトレースを選択して Jaeger UI に移動します。

Jaeger 検索 UI は、現在のリクエストのCorrelation-ID に対するクエリを返します。この検索は単一のトレース結果を返すはずです。この結果を選択すると、トレースの詳細が階層的な時間軸で表示されます。

Jaeger Search UI

GitLab Developer KitなしでJaegerを使う場合

分散トレースは、本番環境やステージング環境だけでなく、GDK以外の開発環境でもトラブルシューティングのために有効にすることができます。現時点では、この機能は実験的なものであり、本番環境ではサポートされていません。この最初のリリースでは、開発環境でのデバッグにのみ使用することを想定しています。

Jaegerトレースは3つのステップで有効にできます:

  1. Jaegerを起動します。
  2. GITLAB_TRACING 環境変数 を設定します。
  3. GitLab アプリケーションを起動します。
  4. ブラウザでJaeger Search UIにアクセスします。

1.イェーガーを起動

Jaegerには多くの設定オプションがありますが、トレース保存にメモリを使用する “all-in-one “モードでの起動は非常に簡単です(したがって非パーシステント)。オールインワン “モードの主な利点は、使いやすさです。

より詳細な設定オプションについては、Jaegerドキュメントを参照してください。

Dockerを使う

Dockerが使えるのであれば、Dockerを使って以下のコマンドでJaeger all-in-oneを実行するのが簡単です:

$ docker run \
  --rm \
  -e COLLECTOR_ZIPKIN_HTTP_PORT=9411  \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 9411:9411 \
  jaegertracing/all-in-one:latest

Jaegerプロセスを使う

Dockerを使わなくても、オールインワン・プロセスのセットアップは簡単です。

  1. あなたのプラットフォーム用の最新のJaegerリリースをダウンロードしてください。
  2. アーカイブを展開し、bin/all-in-one プロセスを実行します。

デフォルトのリスニング・ポートでプロセスが起動するはずです。

2.GITLAB_TRACING 環境変数の設定

Jaegerを起動したら、GITLAB_TRACING 変数に適切な設定文字列を設定します。

同じホストですべてを動かしている場合は、次の値を使います:

export GITLAB_TRACING="opentracing://jaeger?http_endpoint=http%3A%2F%2Flocalhost%3A14268%2Fapi%2Ftraces&sampler=const&sampler_param=1"

この設定文字列は、Jaegerドライバopentracing://jaeger 、以下のオプションを使用します:

名前説明
http_endpointhttp://localhost:14268/api/tracesJaeger がトレース情報をhttp://localhost:14268/ で動いている HTTP エンドポイントに送るように設定します。あるいは、upd_endpoint を使うこともできます。
samplerconstJaeger が定数サンプラーを使用するように設定します (オンまたはオフ)。
sampler_param1 const サンプラーが_すべての_トレースをサンプリングするように設定します。0 を使うとトレースをサンプリング_しません_。

他のパラメータ値も可能です:

名前物件例説明
udp_endpointlocalhost:6831これはデフォルトです。コンパクトなthriftプロトコルを使って、ポート6831 のUDPリスナーにトレース情報を送信するようにJaegerを設定します。このプロトコルを使うとJaeger Client for Rubyでイシューが発生するので注意してください。
samplerprobabalisticJaegerが確率的ランダムサンプラーを使うように設定します。サンプルのレートはsampler_param の値で設定します。
sampler_param0.01 0.01 の比率を使用して、probabalistic サンプラーがトレースの_1%_をランダムにサンプリングするように設定します。
service_nameapiJaegerバックエンドが使用するサービス名をオーバーライドします。このパラメータは、アプリケーションが提供する値よりも優先されます。
note
Workhorse、Gitaly、Rails、Sidekiqを含むすべてのGitLabプロセスの環境変数に同じGITLAB_TRACING 値を設定する必要があります。

3.GitLabアプリケーションを起動します。

GITLAB_TRACING 環境変数がすべての GitLab サービスにエクスポートされたら、アプリケーションを起動します。

GITLAB_TRACING が適切に設定されると、アプリケーションは起動時にこのログを記録します:

13:41:53 gitlab-workhorse.1      | 2019/02/12 13:41:53 Tracing enabled
...
13:41:54 gitaly.1                | 2019/02/12 13:41:54 Tracing enabled
...

GITLAB_TRACING が正しく設定されていない場合、このイシューが記録されます:

13:43:45 gitaly.1                | 2019/02/12 13:43:45 skipping tracing configuration step: tracer: unable to load driver mytracer

デフォルトでは、GitLabはJaegerトレーサーを同梱していますが、コンパイル時に他のトレーサーを含めることができます。この方法の詳細はLabKit tracing documentation に記載されています。

トレースに関するログメッセージが出力されない場合は、GITLAB_TRACING 環境変数が設定されていない可能性があります。

4.Jaeger Search UIを開きます。

デフォルトでは、Jaeger 検索 UI はhttp://localhost:16686/search で利用可能です。

note
Jaeger UIに表示される前に、アプリケーションを使用してトレースを生成する必要があることを忘れないでください。