ブログ | NGINX

NGINX および NGINX Plus 向け OpenTracing

NGINX-F5 水平黒タイプ RGB の一部
モハメド・グーガム サムネイル
モハメド・グーガム
2019年6月17日公開

マイクロサービスアーキテクチャには多くの利点がある一方で、新たな複雑さも生じます。 1 つは、アプリケーションを構成するすべてのマイクロサービス間でデータが流れる中で、リクエストが処理されるにつれてそれを追跡するという課題です。 この目的のために、分散 (リクエスト) トレースと呼ばれる新しい方法論が発明されました。OpenTracing、分散トレース ツールの設計と実装をガイドすることを目的とした API の仕様と標準セットです。

NGINX Plus リリース 18 (R18)では、 NGINX OpenTracing モジュールを動的モジュール リポジトリに追加しました (数年前からGitHub でサードパーティ モジュールとして利用可能でした)。 NGINX OpenTracing モジュールの大きな利点は、分散トレース用に NGINX と NGINX Plus をインストルメント化することで、アプリケーションを個別にインストルメント化することなく、プロキシされたすべてのアプリケーションのトレース データを取得できることです。

このブログでは、NGINX または NGINX Plus (簡潔にするために、以降はNGINX Plusと呼びます) のリクエストの分散トレースを有効にする方法を説明します。 2 つの分散トレース サービス (OpenTracing の用語ではトレーサー)、 JaegerZipkin の説明を提供します。 (他のトレーサーの一覧については、 OpenTracing のドキュメントを参照してください。) トレーサーによって提供される情報の種類を説明するために、NGINX Plus キャッシュを有効にする前と有効にした後のリクエスト処理を比較します。

トレーサーには 2 つの基本コンポーネントがあります。

  • 実行されているホスト上で実行されているアプリケーションからトレース データを収集するエージェント。 この場合、「アプリケーション」は NGINX Plus であり、エージェントはプラグインとして実装されます。
  • 1 つ以上のエージェントからトレース データを受け取り、それを中央 UI に表示するサーバー (コレクターとも呼ばれます)。必要に応じて、NGINX Plus ホストまたは別のホストでサーバーを実行できます。

トレーサーサーバーのインストール

最初のステップは、選択したトレーサー用のサーバーをインストールして構成することです。 ここでは、Jaeger と Zipkin に関する手順を説明します。必要に応じて、他のトレーサーにも適用してください。

Jaeger サーバーのインストール

Jaeger サーバーをインストールするには、次の方法をお勧めします。 手順 1 で指定した URL から Docker イメージをダウンロードすることもできます。

  1. Jaeger のダウンロード ページに移動し、Linux バイナリ (執筆時点ではjaeger-1.12.0-linux-amd64.tar ) をダウンロードします。

  2. バイナリを/usr/bin/jaegerに移動し (必要に応じて最初にディレクトリを作成します)、実行します。

    $ mkdir /usr/bin/jaeger $ mv jaeger-1.12.0-linux-amd64.tar /usr/bin/jaeger $ cd /usr/bin/jaeger $ tar xvzf jaeger-1.12.0-linux-amd64.tar.gz $ sudo rm -rf jaeger-1.12.0-linux-amd64.tar.gz $ cd jaeger-1.12.0-linux-amd64 $ ./jaeger-all-in-one
  3. ブラウザでhttp:// Jaeger-server-IP-address :16686/の Jaeger UI にアクセスできることを確認します (16686 は Jaeger サーバーのデフォルト ポートです)。

Zipkin サーバーのインストール

  1. Zipkin の Docker イメージをダウンロードして実行します (デフォルトのポート 9411 を使用します)。

    $ docker run -d -p 9411:9411 openzipkin/zipkin
  2. ブラウザでhttp:// Zipkin-server-IP-address :9411/の Zipkin UI にアクセスできることを確認します。

トレーサープラグインのインストールと設定

NGINX Plus ホストでこれらのコマンドを実行して、Jaeger または Zipkin のプラグインをインストールします。

Jaeger プラグインのインストール

  1. Jaeger プラグインをインストールします。 次のwgetコマンドは x86‑64 Linux システム用です。

    $ cd /usr/local/lib $ wget https://github.com/jaegertracing/jaeger-client-cpp/releases/download/v0.4.2/libjaegertracing_plugin.linux_amd64.so -O /usr/local/lib/libjaegertracing_plugin.so

    ソースからプラグインをビルドする手順は、 GitHubで入手できます。

  2. 次の内容を含む、 /etc/jaeger/jaeger-config.jsonという名前のプラグインの JSON 形式の設定ファイルを作成します。 Jaeger サーバーのデフォルト ポート 6831 を使用します。

    { "service_name": "nginx", "sampler": { "type": "const", "param": 1 }, "レポーター": { "localAgentHostPort": " Jaeger サーバーの IP アドレス:6831" } }

    サンプラーオブジェクトの詳細については、 Jaeger のドキュメントを参照してください。

Zipkinプラグインのインストール

  1. Zipkin プラグインをインストールします。 次のwgetコマンドは x86‑64 Linux システム用です。

    $ cd /usr/local/lib $ wget -O - https://github.com/rnburn/zipkin-cpp-opentracing/releases/download/v0.5.2/linux-amd64-libzipkin_opentracing_plugin.so.gz | gunzip -c > /usr/local/lib/libzipkin_opentracing_plugin.so
  2. 次の内容を含む、 /etc/zipkin/zipkin-config.jsonという名前のプラグインの JSON 形式の構成ファイルを作成します。 Zipkin サーバーのデフォルト ポート 9411 を使用します。

    { "service_name": "nginx", "collector_host": 「 Zipkin サーバーの IP アドレス」、「コレクター ポート」: 9411 }

    構成オブジェクトの詳細については、 GitHub の JSON スキーマを参照してください。

NGINX Plusの設定

NGINX Plus ホストで次の手順を実行します。

  1. NGINX Plus 管理者ガイドの指示に従って、NGINX OpenTracing モジュールをインストールします。

  2. メインの NGINX Plus 設定ファイル ( /etc/nginx/nginx.conf ) のメイン (最上位) コンテキストに次のload_moduleディレクティブを追加します。

    モジュールモジュール/ngx_http_opentracing_module.so をロードします。
  3. NGINX Plus 設定に次のディレクティブを追加します。

    従来の設定スキームを使用する場合は、 /etc/nginx/conf.d/opentracing.confという新しいファイルにディレクティブを配置します。 また、 /etc/nginx/nginx.confhttpコンテキストに次のincludeディレクティブが表示されていることを確認します。

    http {
    /etc/nginx/conf.d/*.conf を含めます。
    }
    • opentracing_load_tracerディレクティブはトレーサー プラグインを有効にします。 必要に応じて、Jaeger または Zipkin のディレクティブのコメントを解除します。
    • opentracing_tagディレクティブにより、NGINX Plus 変数をトレーサー UI に表示される OpenTracing タグとして使用できるようになります。
    • OpenTracing アクティビティをデバッグするには、 log_formatおよびaccess_logディレクティブのコメントを解除します。 デフォルトの NGINX アクセス ログとログ形式をこれに置き換える場合は、ディレクティブのコメントを解除し、「 opentracing 」の 3 つのインスタンスを「 main 」に変更します。 もう 1 つのオプションは、ポート 9001 のトラフィックの OpenTracing アクティビティのみをログに記録することです。log_formatおよびaccess_logディレクティブのコメントを解除し、それらをサーバーブロックに移動します。
    • サーバーブロックは、次のセクションで説明するサンプル Ruby アプリケーション用に OpenTracing をセットアップします。
    # ベンダー トレーサーをロードします#opentracing_load_tracer /usr/local/libjaegertracing_plugin.so 
    # /etc/jaeger/jaeger-config.json;
    #opentracing_load_tracer /usr/local/lib/libzipkin_opentracing_plugin.so
    # /etc/zipkin/zipkin-config.json;
    
    # すべてのリクエストのトレースを有効にします
    opentracing on;
    
    # NGINX Plus 変数の値をキャプチャする追加のタグを設定します
    opentracing_tag bytes_sent $bytes_sent;
    opentracing_tag http_user_agent $http_user_agent;
    opentracing_tag request_time $request_time;
    opentracing_tag upstream_addr $upstream_addr;
    opentracing_tag upstream_bytes_received $upstream_bytes_received; opentracing_tag アップストリーム キャッシュ ステータス $upstream_cache_status;
    opentracing_tag アップストリーム接続時間 $upstream_connect_time;
    opentracing_tag アップストリーム ヘッダー時間 $upstream_header_time;
    opentracing_tag アップストリーム キュー時間 $upstream_queue_time;
    opentracing_tag アップストリーム応答時間 $upstream_response_time;
    
    #デバッグ用にコメントを解除
    # log_format opentracing '$remote_addr - $remote_user [$time_local] "$request" '
    # '$status $body_bytes_sent "$http_referer" '
    # '"$http_user_agent" "$http_x_forwarded_for" '
    # '"$host" sn="$server_name" '
    # 'rt=$request_time '
    # 'ua="$upstream_addr" us="$upstream_status" '
    # 'ut="$upstream_response_time" ul="$upstream_response_length" '
    # 'cs=$upstream_cache_status';
    #access_log /var/log/nginx/opentracing.log opentracing;
    
    server {
    listen 9001;
    
    location / {
    # OpenTracing Spans に使用される操作名は、デフォルトで 'location' ブロックの名前になりますが、カスタマイズするにはこのディレクティブのコメントを解除します。
    #opentracing_operation_name $uri;
    
    # アクティブな Span コンテキストを上流に伝播して、トレースをバックエンドで続行できるようにします。
    opentracing_propagate_context;
    
    # Ruby アプリがポート 4567 でリッスンしていることを確認します
    proxy_pass http://127.0.0.1:4567;
    }
    }
  4. NGINX Plus 構成を検証して再ロードします。

    $ nginx -t $ nginx -s リロード

サンプルRubyアプリの設定

トレーサーと NGINX Plus の設定が完了したら、OpenTracing データの外観を示すサンプル Ruby アプリを作成します。 このアプリを使用すると、NGINX Plus キャッシュによって応答時間がどの程度改善されるかを測定できます。 アプリは、 /に対する次の HTTP GETリクエストのようなリクエストを受信すると、応答する前にランダムな時間 (2 ~ 5 秒) 待機します。

$ curl http:// NGINX-Plus IPアドレス:9001/
  1. RubySinatra (他の Ruby Web アプリケーション フレームワークの代替として Ruby で記述されたオープン ソース ソフトウェア Web アプリケーション ライブラリおよびドメイン固有言語) の両方をインストールして設定します。

  2. 次の内容を含むapp.rbというファイルを作成します。

    #!/usr/bin/ruby
    
    require 'sinatra'
    
    get '/*' do
    out = "<h1>Ruby simple app</h1>" + "\n"
    
    #2 秒から 5 秒の間のランダムな時間スリープします
    sleeping_time = rand(4)+2
    sleep(sleeping_time)
    puts "スリープ時間: #{sleeping_time} 秒。"
    out += '<p>出力テキスト</p>' + "\n"
    
    return out
    end
  3. app.rb を実行可能にして実行します。

    $ chmod +x app.rb $ ./app.rb

キャッシュなしで応答時間をトレースする

Jaeger と Zipkin を使用して、キャッシュが有効になっていない場合に NGINX Plus がリクエストに応答するまでにかかる時間を示します。 トレーサーごとに 5 つのリクエストを送信します。

キャッシュなしの Jaeger からの出力

Jaeger UI に表示される 5 つのリクエストは次のとおりです (最新のものから順に):

Ruby アプリ コンソールに同じ情報が表示されます。

- -> /スリープ時間: 3秒。 
127.0.0.1 - - [2019年6月7日: 10:50:46 +0000] "GET / HTTP/1.1" 200 49 3.0028
127.0.0.1 - - [2019年6月7日: 10:50:43 UTC] "GET / HTTP/1.0" 200 49
- -> /
スリープ時間: 2秒。 
127.0.0.1 - - [2019年6月7日: 10:50:56 +0000] "GET / HTTP/1.1" 200 49 2.0018 
127.0.0.1 - - [2019年6月7日: 10:50:54 UTC] "GET / HTTP/1.0"1 200 49
- -> /
スリープ時間: 3秒。 
127.0.0.1 - - [2019年6月7日: 10:53:16 +0000] "GET / HTTP/1.1" 200 49 3.0029 
127.0.0.1 - - [2019年6月7日: 10:53:13 UTC] "GET / HTTP/1.0" 200 49
- -> /
スリープ時間: 4秒。
127.0.0.1 - - [2019年6月7日: 10:54:03 +0000] "GET / HTTP/1.1" 200 49 4.0030 
127.0.0.1 - - [2019年6月7日: 10:53:59 UTC] "GET / HTTP/1.0" 200 49
- -> /
スリープ時間: 3秒。
127.0.0.1 - - [2019年6月7日: 10:54:11 +0000] "GET / HTTP/1.1" 200 49 3.0012
127.0.0.1 - - [2019年6月7日: 10:54:08 UTC] "GET / HTTP/1.0" 200 49

Jaeger UI で最初の (最新の) リクエストをクリックすると、タグとして追加した NGINX Plus 変数の値などの詳細が表示されます。

キャッシュなしの Zipkin からの出力

Zipkin UI の別の 5 つのリクエストを次に示します。

Ruby アプリ コンソールにも同じ情報が表示されます。

- -> /スリープ時間: 2秒。
127.0.0.1 - - [2019年6月7日: 10:31:18 +0000] "GET / HTTP/1.1" 200 49 2.0021 
127.0.0.1 - - [2019年6月7日: 10:31:16 UTC] "GET / HTTP/1.0" 200 49
- -> /
スリープ時間: 3秒。
127.0.0.1 - - [2019年6月7日: 10:31:50 +0000] "GET / HTTP/1.1" 200 49 3.0029 
127.0.0.1 - - [2019年6月7日: 10:31:47 UTC] "GET / HTTP/1.0" 200 49
- -> /
スリープ時間: 3秒。
127.0.0.1 - - [2019年6月7日: 10:32:08 +0000] "GET / HTTP/1.1" 200 49 3.0026 
127.0.0.1 - - [2019年6月7日: 10:32:05 UTC] "GET / HTTP/1.0" 200 49
- -> /
スリープ時間: 3秒。
127.0.0.1 - - [2019年6月7日: 10:32:32 +0000] "GET / HTTP/1.1" 200 49 3.0015 
127.0.0.1 - - [2019年6月7日: 10:32:29 UTC] "GET / HTTP/1.0" 200 49
- -> /
スリープ時間: 5秒。
127.0.0.1 - - [2019年6月7日: 10:32:52 +0000] "GET / HTTP/1.1" 200 49 5.0030 
127.0.0.1 - - [2019年6月7日: 10:32:47 UTC] "GET / HTTP/1.0" 200 49

Zipkin UI で最初のリクエストをクリックすると、タグとして追加した NGINX Plus 変数の値などの詳細が表示されます。

キャッシュによる応答時間の追跡

NGINX Plus キャッシュの設定

NGINX Plus の設定で作成したopentracing.confファイルにディレクティブを追加して、キャッシュを有効にします。

  1. httpコンテキストで、次のproxy_cache_pathディレクティブを追加します。

    proxy_cache_path /data/nginx/cache keys_zone=one:10m;
  2. サーバーブロックに、次のproxy_cacheおよびproxy_cache_validディレクティブを追加します。

    proxy_cache 1;
    proxy_cache_valid 任意 1m;
  3. 構成を検証して再読み込みします。

    $ nginx -t $ nginx -s リロード

キャッシュを使用した Jaeger からの出力

以下は 2 つのリクエスト後の Jaeger UI です。

最初の応答 (ラベル13f69db ) には 4 秒かかりました。 NGINX Plus は応答をキャッシュし、約 15 秒後にリクエストが繰り返されたとき、応答は NGINX Plus キャッシュから取得されたため、2 ミリ秒 (ms) 未満で完了しました。

2 つのリクエストを詳細に見ると、応答時間の違いがわかります。 最初のリクエストでは、 upstream_cache_statusMISSです。これは、要求されたデータがキャッシュになかったことを意味します。 Ruby アプリにより 4 秒の遅延が追加されました。

2 番目のリクエストでは、 upstream_cache_statusHITです。 データはキャッシュから取得されるため、Ruby アプリは遅延を追加できず、応答時間は 2 ミリ秒未満になります。 空のupstream_*値は、アップストリーム サーバーがこの応答に関与していなかったことも示します。

キャッシュ付き Zipkin からの出力

キャッシュが有効になっている 2 つのリクエストに対する Zipkin UI の表示は、同様の図を描きます。

もう一度 2 つのリクエストを詳細に見ると、応答時間の違いがわかります。 最初のリクエストでは応答がキャッシュされず ( upstream_cache_statusMISS )、Ruby アプリは (偶然にも) Jaeger の例と同じ 4 秒の遅延を追加します。

2 番目のリクエストを行う前に応答がキャッシュされているため、 upstream_cache_statusHITです。

結論

NGINX OpenTracing モジュールは、NGINX Plus のリクエストとレスポンスのトレースを可能にし、OpenTracing タグを使用して NGINX Plus 変数にアクセスできるようにします。 このモジュールではさまざまなトレーサーも使用できます。

NGINX OpenTracing モジュールの詳細については、GitHub のNGINX OpenTracingモジュール リポジトリをご覧ください。

NGINX Plus で OpenTracing を試すには、今すぐ30 日間の無料トライアルを開始するか、弊社にお問い合わせの上、使用事例についてご相談ください


「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"