マイクロサービスアーキテクチャには多くの利点がある一方で、新たな複雑さも生じます。 1 つは、アプリケーションを構成するすべてのマイクロサービス間でデータが流れる中で、リクエストが処理されるにつれてそれを追跡するという課題です。 この目的のために、分散 (リクエスト) トレースと呼ばれる新しい方法論が発明されました。OpenTracingは、分散トレース ツールの設計と実装をガイドすることを目的とした API の仕様と標準セットです。
NGINX Plus リリース 18 (R18)では、 NGINX OpenTracing モジュールを動的モジュール リポジトリに追加しました (数年前からGitHub でサードパーティ モジュールとして利用可能でした)。 NGINX OpenTracing モジュールの大きな利点は、分散トレース用に NGINX と NGINX Plus をインストルメント化することで、アプリケーションを個別にインストルメント化することなく、プロキシされたすべてのアプリケーションのトレース データを取得できることです。
このブログでは、NGINX または NGINX Plus (簡潔にするために、以降はNGINX Plusと呼びます) のリクエストの分散トレースを有効にする方法を説明します。 2 つの分散トレース サービス (OpenTracing の用語ではトレーサー)、 JaegerとZipkin の説明を提供します。 (他のトレーサーの一覧については、 OpenTracing のドキュメントを参照してください。) トレーサーによって提供される情報の種類を説明するために、NGINX Plus キャッシュを有効にする前と有効にした後のリクエスト処理を比較します。
トレーサーには 2 つの基本コンポーネントがあります。
最初のステップは、選択したトレーサー用のサーバーをインストールして構成することです。 ここでは、Jaeger と Zipkin に関する手順を説明します。必要に応じて、他のトレーサーにも適用してください。
Jaeger サーバーをインストールするには、次の方法をお勧めします。 手順 1 で指定した URL から Docker イメージをダウンロードすることもできます。
Jaeger のダウンロード ページに移動し、Linux バイナリ (執筆時点ではjaeger-1.12.0-linux-amd64.tar ) をダウンロードします。
バイナリを/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
ブラウザでhttp:// Jaeger-server-IP-address :16686/の Jaeger UI にアクセスできることを確認します (16686 は Jaeger サーバーのデフォルト ポートです)。
Zipkin の Docker イメージをダウンロードして実行します (デフォルトのポート 9411 を使用します)。
$ docker run -d -p 9411:9411 openzipkin/zipkin
ブラウザでhttp:// Zipkin-server-IP-address :9411/の Zipkin UI にアクセスできることを確認します。
NGINX Plus ホストでこれらのコマンドを実行して、Jaeger または Zipkin のプラグインをインストールします。
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で入手できます。
次の内容を含む、 /etc/jaeger/jaeger-config.jsonという名前のプラグインの JSON 形式の設定ファイルを作成します。 Jaeger サーバーのデフォルト ポート 6831 を使用します。
{ "service_name": "nginx", "sampler": { "type": "const", "param": 1 }, "レポーター": { "localAgentHostPort": " Jaeger サーバーの IP アドレス:6831" } }
サンプラー
オブジェクトの詳細については、 Jaeger のドキュメントを参照してください。
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
次の内容を含む、 /etc/zipkin/zipkin-config.jsonという名前のプラグインの JSON 形式の構成ファイルを作成します。 Zipkin サーバーのデフォルト ポート 9411 を使用します。
{ "service_name": "nginx", "collector_host": 「 Zipkin サーバーの IP アドレス」、「コレクター ポート」: 9411 }
構成オブジェクトの詳細については、 GitHub の JSON スキーマを参照してください。
NGINX Plus ホストで次の手順を実行します。
NGINX Plus 管理者ガイドの指示に従って、NGINX OpenTracing モジュールをインストールします。
メインの NGINX Plus 設定ファイル ( /etc/nginx/nginx.conf ) のメイン (最上位) コンテキストに次のload_module
ディレクティブを追加します。
モジュールモジュール/ngx_http_opentracing_module.so をロードします。
NGINX Plus 設定に次のディレクティブを追加します。
従来の設定スキームを使用する場合は、 /etc/nginx/conf.d/opentracing.confという新しいファイルにディレクティブを配置します。 また、 /etc/nginx/nginx.confのhttp
コンテキストに次のinclude
ディレクティブが表示されていることを確認します。
http {
/etc/nginx/conf.d/*.conf を含めます。
}
opentracing_load_tracer
ディレクティブはトレーサー プラグインを有効にします。 必要に応じて、Jaeger または Zipkin のディレクティブのコメントを解除します。opentracing_tag
ディレクティブにより、NGINX Plus 変数をトレーサー UI に表示される 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;
}
}
NGINX Plus 構成を検証して再ロードします。
$ nginx -t $ nginx -s リロード
トレーサーと NGINX Plus の設定が完了したら、OpenTracing データの外観を示すサンプル Ruby アプリを作成します。 このアプリを使用すると、NGINX Plus キャッシュによって応答時間がどの程度改善されるかを測定できます。 アプリは、 /に対する次の HTTP GET
リクエストのようなリクエストを受信すると、応答する前にランダムな時間 (2 ~ 5 秒) 待機します。
$ curl http:// NGINX-Plus IPアドレス:9001/
RubyとSinatra (他の Ruby Web アプリケーション フレームワークの代替として Ruby で記述されたオープン ソース ソフトウェア Web アプリケーション ライブラリおよびドメイン固有言語) の両方をインストールして設定します。
次の内容を含む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
app.rb を実行可能にして実行します。
$ chmod +x app.rb $ ./app.rb
Jaeger と Zipkin を使用して、キャッシュが有効になっていない場合に NGINX Plus がリクエストに応答するまでにかかる時間を示します。 トレーサーごとに 5 つのリクエストを送信します。
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 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 の設定で作成したopentracing.confファイルにディレクティブを追加して、キャッシュを有効にします。
http
コンテキストで、次のproxy_cache_path
ディレクティブを追加します。
proxy_cache_path /data/nginx/cache keys_zone=one:10m;
サーバー
ブロックに、次のproxy_cache
およびproxy_cache_valid
ディレクティブを追加します。
proxy_cache 1;
proxy_cache_valid 任意 1m;
構成を検証して再読み込みします。
$ nginx -t $ nginx -s リロード
以下は 2 つのリクエスト後の Jaeger UI です。
最初の応答 (ラベル13f69db ) には 4 秒かかりました。 NGINX Plus は応答をキャッシュし、約 15 秒後にリクエストが繰り返されたとき、応答は NGINX Plus キャッシュから取得されたため、2 ミリ秒 (ms) 未満で完了しました。
2 つのリクエストを詳細に見ると、応答時間の違いがわかります。 最初のリクエストでは、 upstream_cache_status
はMISS
です。これは、要求されたデータがキャッシュになかったことを意味します。 Ruby アプリにより 4 秒の遅延が追加されました。
2 番目のリクエストでは、 upstream_cache_status
はHIT
です。 データはキャッシュから取得されるため、Ruby アプリは遅延を追加できず、応答時間は 2 ミリ秒未満になります。 空のupstream_*
値は、アップストリーム サーバーがこの応答に関与していなかったことも示します。
キャッシュが有効になっている 2 つのリクエストに対する Zipkin UI の表示は、同様の図を描きます。
もう一度 2 つのリクエストを詳細に見ると、応答時間の違いがわかります。 最初のリクエストでは応答がキャッシュされず ( upstream_cache_status
がMISS
)、Ruby アプリは (偶然にも) Jaeger の例と同じ 4 秒の遅延を追加します。
2 番目のリクエストを行う前に応答がキャッシュされているため、 upstream_cache_status
はHIT
です。
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 コンテンツにリダイレクトされます。"