見積もりリクエストの実際の宛先を追う

LinuxBeginner
オンラインで実践に進む

はじめに

PARCEL は架空のギフト店です。訪問者は Arc lamp や Clay vase を見て、配送と受け取りを比較します。受け取りの見積もりは返りますが、配送は失敗します。新しく失敗したリクエストを入口から応答したサービスまで追跡し、受け取りを壊さず正しい配送料金を復旧してください。

基本的なターミナル操作ができれば十分です。短い Nginx 設定ファイル2つを編集し、実ログを読み、実際の応答を試します。アプリのプログラミング、SDK、外部アカウント、購入、個人情報は不要です。すべてのサービスは同じ準備済み練習インスタンスで動作します。これはリクエストの関連付けであり、完全な分散トレーシング基盤ではありません。

閲覧と見積もりには Website を使います。コマンドはすべて Workstation で実行します。開始ディレクトリは /home/labex/project/parcel です。各単元には独立した環境があります。ポート 8081 の入口は見積もりごとに1つのバックエンドへ転送します。配送は 8091、受け取りは 8092 で待ち受けます。ポートはネットワークサービスを識別します。Workstation で使う 127.0.0.1 は、このラボのインスタンスを意味します。

新しいリクエストに共通の参照番号を付ける

このステップでは、通常の顧客の操作を確認し、失敗を観察して、新しいリクエストを2つの実ログで関連付けます。Website から始めます。

店を見てみる

Two good things の Arc lamp を開きます。詳細には $48 とローカルのイラストが表示されます。Estimate collection を選び、Arc lamp と Near のまま Get estimate をクリックします。**$2.00** と HTTP 200 が表示されるはずです。これが維持すべき正常な機能です。PARCEL↗ でホームへ戻り、Delivery を開いて Get estimate を押します。Estimate unavailable と HTTP 404 が表示されます。

HTTP はブラウザーが使うリクエストと応答のプロトコルです。200 は成功した応答、404 は受信したサービスに要求されたパスがないことを意味します。接続エラーは別で、利用できるサーバー応答を受け取れていない状態です。現在の参照番号は not available なので、顧客の応答とサービスログを簡単には結び付けられません。

完全な商品リンクを備えた PARCEL の店

証拠を理解する

準備済みの入口ログには、Nginx が各リクエストに生成した識別子がすでに記録されます。バックエンドには転送された識別子を記録する機能があります。接続すると、1回の失敗について次のような記録ができます。点は自分の識別子を表します。

entry:    {"id":"...","path":"/api/delivery","status":404,"upstream":"127.0.0.1:8091","upstream_status":"404"}
delivery: {"service":"delivery","id":"...","path":"/v1/shipping","status":404}

入口のパスはブラウザーが要求したものです。バックエンドのパスは入口が実際に転送したものです。upstream は接続先のアドレス、upstream_status はその実際の応答ステータスです。同じ識別子が2つの観察をつなぎます。多数のリクエストでは時刻だけの比較は確実ではありません。リクエスト本文や秘密情報は記録しません。

識別子をつなぐ

Workstation に切り替えます。pwd は現在のディレクトリ、cat はファイルの内容を表示します。

pwd

/home/labex/project/parcel と表示されます。別の場所に移動した場合は cd /home/labex/project/parcel を実行します。cd は現在のディレクトリを変更します。correlation.conf のように / で始まらないパスは、そのディレクトリからの相対パスです。

cat correlation.conf

今はコメントだけです。Nginx は準備済みの入口サーバーです。設定はセミコロンで終わるディレクティブで構成されます。主設定がこの小さなファイルを読み込むため、主設定の枠組みを編集する必要はありません。

ヘッダーは HTTP リクエストまたは応答と一緒に運ぶ、名前付きの値です。proxy_set_header はバックエンドへ送るヘッダーを設定し、add_header は顧客への応答に追加します。$request_id は Nginx が今回生成した値です。always は成功だけでなく失敗時にもヘッダーを含めます。ここでは双方で X-Request-ID という名前を使います。入口は訪問者の識別子を信頼せず、自分で生成します。

cat > correlation.conf はヒアドキュメントでファイルを置き換えます。最後の CONF を単独の行にするところまで、ブロック全体を貼り付けてください。'CONF' の引用符は $request_id を文字どおり残し、シェルではなく Nginx が解釈できるようにします。

cat > correlation.conf <<'CONF'
proxy_set_header X-Request-ID $request_id;
add_header X-Request-ID $request_id always;
CONF

保存した内容を読み、提供された補助スクリプトで適用します。bash はそのシェルスクリプトを実行します。先に構文を検査し、有効な場合だけ Nginx を再読み込みします。ルートを修復したり、料金を判定したりはしません。

cat correlation.conf
bash reload.sh

設定テストの成功と Configuration accepted. Send a new request to test it. を確認します。行のエラーが出たら、綴り、セミコロン、文字どおりのドル記号をブロックと比較し、ファイルを再作成して再試行します。構文検査に失敗しても、以前の設定がサービスを続けます。再読み込みで古い応答は変わらないので、新しいリクエストを送ります。

自分の新しい失敗を追う

Website の Delivery で Get estimate を再度押します。まだ失敗しますが、Request reference は32桁の16進数になります。この新しい値を正確にコピーしてください。例の点やスクリーンショットの識別子は使いません。

Workstation に戻ります。シェル変数は後のコマンドで使う値を保存します。次の PASTE_YOUR_NEW_REQUEST_REFERENCE_HERE を、Website からコピーした正確な新しい参照番号に置き換えます。単一引用符は残し、= の前後に空白を入れません。引用符は文字どおりの値を保持します。仮の文字列のまま実行しないでください。

REQUEST_ID='PASTE_YOUR_NEW_REQUEST_REFERENCE_HERE'

grep は一致する行を表示します。-F は値を通常の文字列として扱い、二重引用符は変数の値をひとまとまりにします。次の絶対パスはどのディレクトリからでも使えます。

grep -F "$REQUEST_ID" /var/log/parcel/entry.jsonl
grep -F "$REQUEST_ID" /var/log/parcel/delivery.jsonl

両方にまったく同じ識別子、バックエンドのパス /v1/shipping、ステータス 404 があるはずです。配送が応答するバックエンドに届いたと分かります。停止したサービスや接続の欠如ではありません。空の出力は古い参照番号や入力ミスでよく起こります。Website で再要求し、新しい値をコピーして REQUEST_ID を設定し直します。応答ヘッダーだけを有効にしてもバックエンドの値は - のままです。両方のディレクティブが必要です。

このステップのチェックは新しい読み取り専用のリクエストで関連付けを試します。特定のシェル変数、コマンド履歴、コピーしたログファイルは要求しません。

ルートを復旧して両方の見積もりを維持する

このステップでは、2つのログ記録とサービス契約を使って配送を修正します。Workstation から始めます。

アドレスとパスを分ける

cat でルーティング設定を表示します。

cat routes.conf

location = ブロックは公開パスに完全一致します。波括弧はディレクティブをまとめます。proxy_pass は Nginx に転送先を指定します。http://127.0.0.1:8091/v1/shipping では、アドレスとポートがサービスを選び、/v1/shipping がその中の操作を選びます。どちらも誤る可能性があります。この完全一致の location では、設定したバックエンドパスが一致した公開パスを置き換えます。クエリーの選択値は引き続き転送されます。

準備済みサービスの契約は次のとおりです。

公開操作 担当サービス サービスのアドレス バックエンドパス
配送 delivery http://127.0.0.1:8091 /v1/delivery
受け取り collection http://127.0.0.1:8092 /v1/collection

両方とも /health に応答しますが、正常稼働だけではルーティングの正しさは分かりません。ログでは配送が 8091 の /v1/shipping に届いています。配送担当のサービスではありますが、このパスはありません。契約は /v1/delivery を要求しています。受け取りはアドレスもパスも正しい状態です。

小さな修正を適用する

受け取りを残し、編集可能なルートファイルだけを置き換えます。

cat > routes.conf <<'CONF'
location = /api/delivery {
    proxy_pass http://127.0.0.1:8091/v1/delivery;
}
location = /api/collection {
    proxy_pass http://127.0.0.1:8092/v1/collection;
}
CONF
bash reload.sh

構文検査が失敗したら、波括弧とセミコロンを比較し、書き直して再試行します。準備済みのバックエンド、サイト、ログ、主設定は編集しません。正しい実見積もりなしに 200 を返すだけでは、欠陥を隠すことになります。

実料金と関連付けを試す

Website の Delivery で Arc lamp / Near を再要求します。**$6.00、HTTP 200、新しい参照番号が必要です。Clay vase / Far** を要求すると $13.00 になります。Collection では Arc lamp / Near が引き続き $2.00、Clay vase / Far が $4.00 であることを確認します。クリックごとに新しいリクエストなので参照番号も変わります。PARCEL↗ から商品ページに戻っても画像と価格が表示される必要があります。

固有の参照番号を持つ復旧後の配送見積もり

Workstation に戻ります。curl は HTTP リクエストを送信します。-sS は進捗を隠して接続エラーを表示し、-i は応答ヘッダーを含めます。単一引用符は & を URL 内に残し、シェルの解釈を防ぎます。? の後のクエリーは商品と距離を選びます。

curl -sS -i 'http://127.0.0.1:8081/api/delivery?item=vase&zone=far'

HTTP/1.1 200 OK、X-Request-ID ヘッダー、"service": "delivery"、"amount": 13、"currency": "USD" を含む JSON が返ります。JSON は名前付きの値を表すテキスト形式です。本文の request_id はヘッダーと一致する必要があります。ヘッダー名の大文字小文字は違っても意味は変わりません。

この応答の参照番号で、REQUEST_ID を設定し直し、ステップ1の2つの grep -F を繰り返します。両方のログが 200 となり、delivery ログのパスは /v1/delivery になります。古い 404 は有用な履歴です。消したり書き換えたりしないでください。

維持した機能も別に確認します。

curl -sS -i 'http://127.0.0.1:8081/api/collection?item=lamp&zone=near'

200、"service": "collection"、"amount": 2 が必要です。404 を受け取ること自体は通常の HTTP 応答なので、HTTP エラーを失敗扱いにするオプションのない curl は正常終了する場合があります。接続エラーならプロセス停止やアドレス違いが考えられます。前述のパスの証拠と混同せず、最後に動作した設定を見直します。

最終チェックは両操作の商品と距離の全組み合わせを要求し、新しい識別子を実サービスログと照合して、完全な顧客サイトを試します。通常のアクセスログだけが追記されます。採点は設定の再読み込み、ファイルの書き換え、注文作成を行いません。

まとめ

生成した共通の参照番号で、新しいリクエストの入口とバックエンドのログを関連付けました。応答するサービスのパス不在と接続失敗を区別し、実際のルートを修正しました。複数の業務結果を試し、受け取りも維持しました。独立チャレンジでは、同じアドレス・パスと関連付けの方法で、受信するサービスの違いに取り組みます。