Nginx におけるサーバーとロケーションのマッチングロジックの詳細な理解

Nginx におけるサーバーとロケーションのマッチングロジックの詳細な理解

サーバーマッチングロジック

Nginx は、リクエストを実行するサーバー ブロックを決定するときに、サーバー ブロック内の listen フィールドと server_name フィールドに注目します。

listen ディレクティブ

listen フィールドは、サーバーが応答する IP とポートを定義します。listen フィールドが明示的に設定されていない場合、デフォルトのリスナーは 0.0.0.0:80 (ルート) または 0.0.0.0:8080 (非ルート) になります。

listen は次のように設定できます。

  1. IPとポートの組み合わせ
  2. デフォルトでポート80をリッスンする単一のIP
  3. デフォルトですべての IP インターフェースをリッスンする単一のポート
  4. Unixソケットパス

最後のものは通常、異なるサーバー間でリクエストを転送するためにのみ使用されます。

使用するサーバーを選択するためのルールは次のとおりです。

  1. Nginx はまず、listen フィールドのない listen 命令を listen 0.0.0.0:80 に変換し、listen 1.1.1.1 を listen 1.1.1.1:80 に変換するなど、すべての「不完全な」 listen 命令を変換します。
  2. Nginx は、要求された IP とポートに基づいて、要求に最も一致するサーバー ブロックのリストを作成し、特定の IP を指定するサーバー ブロックを優先し、次に listen 0.0.0.0 などのサーバー ブロックを選択します。どちらの場合も、ポートは完全に一致する必要があります。
  3. 最適な一致が 1 つだけの場合は、一致するサーバー ブロックが要求への応答に使用され、それ以外の場合は各サーバー ブロックの server_name ディレクティブが評価されます。

繰り返しになりますが、server_name ディレクティブは、listen ディレクティブが最適な一致を見つけられない場合にのみ評価されます。

たとえば、example.com ドメインが 192.168.0.1 を指しており、192.168.0.1 上の nginx には次の 2 つのサーバー ブロックしかないとします。

# サーバーブロック 1server {
  192.168.0.1 をリッスンします。
  サーバー名 other.com
  ...
}

# サーバーブロック 2server {
  聞く 80;
  サーバー名 example.com
  ...
}

Server_name ディレクティブ

listen ディレクティブに従って最適な一致が見つからない場合は、server_name ディレクティブが解析されます。Nginx はリクエスト内の「Host」ヘッダーをチェックします。この値には、クライアントが実際に要求しようとしているドメイン名または IP アドレスが含まれます。Nginx はこの値に基づいて server_name ディレクティブを一致させます。一致ルールは次のとおりです。

  1. Nginx は、server_name と Host の値に完全に一致するサーバー ブロックを見つけようとします。完全に一致するものが複数見つかった場合は、最初に一致するサーバー ブロックが使用されます。
  2. 完全に一致するサーバー ブロックが見つからない場合、nginx は server_name が * で始まるサーバー ブロックを検索します。複数のサーバー ブロックが見つかった場合は、最も長く一致するサーバー ブロックが選択されます。
  3. で始まるサーバー ブロックが見つからない場合は、で終わるサーバー ブロックが検索されます。また、複数の一致がある場合は、最も長い一致が選択されます。
  4. * に一致するサーバー ブロックが見つからない場合は、正規表現 (~ で始まる) を使用して server_name を定義するサーバー ブロックが検索されます。複数の一致が見つかった場合は、最初の一致が使用されます。
  5. 正規表現に一致するサーバー ブロックが見つからない場合、nginx は listen フィールドに一致するデフォルトのサーバー ブロックを選択します。各 IP とポートの組み合わせは、1 つのデフォルトの default_server ブロックのみで設定できます。何もない場合は、使用可能なリストの最初のサーバーが選択されます (この時点では選択はランダムで、順序は固定されていません)。

次に例を示します。

(1)正確なserver_nameのマッチング、例:

サーバー{
   聞く 80;
   サーバー名 www.domain.com;
   ...
}

(2)ワイルドカード文字*で始まる文字列:

サーバー{
   聞く 80;
   サーバー名 *.domain.com;
   ...
}

(3)ワイルドカード文字*で終わる文字列:

サーバー{
   聞く 80;
   サーバー名 www.*;
   ...
}

(4)正規表現のマッチング:

サーバー{
   聞く 80;
   サーバー名 ~^(?.+)\.ドメイン\.com$;
   ...
}

(5) 上記のいずれにも一致しない場合は、default_server が使用されます。default_server が指定されていない場合は、最初に利用可能なサーバーが選択されます。一致するホスト値がない場合、クライアントにエラーが返されるように指定できます。これにより、他の人があなたのウェブサイトにジャンクトラフィックをリダイレクトするのを防ぐことができます。

サーバー{
  80 default_server をリッスンします。
  server_name _; 444 を返します。
}

nginxの非標準エラーコード444を返して、nginxをブラウザから切断します。

位置マッチングロジック

場所構文解析

場所 オプション修飾子 場所の一致 {
  ...
}

利用可能な修飾子は次のとおりです

決定ルール

1. Nginxはまずプレフィックスベースの場所の一致(つまり正規表現を含まない一致)をチェックします。

2. = 修飾子を使用したロケーション ブロックが要求された URL と完全に一致する場合、そのロケーションは要求に応答するために直ちに使用されます。

3. = 修飾子に一致するロケーション ブロックが見つからない場合は、不正確なプレフィックスの計算が続行され、指定された URI に従って最も長く一致するプレフィックスが検索され、次の処理が実行されます。

(1)最も長く一致する場所に^~修飾子がある場合、nginxはすぐにその場所を使用してリクエストに応答します。

(2)最も長い一致箇所に^~修飾子がない場合、nginxは一致箇所を一時的に保存し、その後に続く一致箇所に進みます。

4. 最も長く一致するプレフィックス ロケーション ブロックを決定して保存した後、nginx は正規表現の一致するロケーション (大文字と小文字を区別する/区別しない) のチェックを続行します。要件を満たす正規表現がある場合は、要求された URI に一致する最初の正規表現ロケーションが選択され、要求に応答します。

5. 要求された URI に一致する正規表現の場所が見つからない場合は、以前に保存された最長のプレフィックスの場所を使用して要求に応答します。

補充する

通常、リクエストに応答する場所が選択されると、他の場所に関係なく、その場所でリクエストが処理されます。ただし、場所内の一部の指示により、新しい場所の一致がトリガーされます。たとえば、次のようになります。

(1) トライファイル

(2)書き直す

(3) エラーページ

https の default_server の設定の詳細については、「https 用の「デフォルト」 nginx サーバーを適切に設定する」を参照してください。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • 1 つの記事で Nginx ロケーション マッチングの実装を理解する
  • Nginx 設定場所のマッチング優先順位の簡単な分析
  • Nginx ロケーション設定(ロケーションのマッチング順序)の詳細な説明
  • nginx のロケーションと書き換えの使用法の詳細な説明
  • Nginx 構成の場所の一致ルールの例の説明

<<:  Vue.js ドロップダウン コンポーネント付きテキストボックス

>>:  MySQL でのテーブルの作成と削除の詳細な例

推薦する

Vueは左上と右上のスライドナビゲーションを実装します

ナビゲーションなどは日々の開発でよく使うので、記録として記事を書きます。ナビゲーションは終了/開始位...

Vue要素ツリーコントロールに点線を追加する詳細な説明

目次1. 成果を達成する2. 実装コード3. その他の実装要約する1. 成果を達成する 2. 実装コ...

モバイルレイアウトにvw+remを使用する方法

まだ rem フレキシブルレイアウトを使用していますか?圧縮された js コードの大きなセクションを...

MySQL 5.7.18 インストーラーのインストール ダウンロード グラフィック チュートリアル

この記事では、MySQL 5.7.18インストーラーの詳細なインストールチュートリアルを参考までに記...

js はマウスによる画像の切り替えを実装します (タイマーなし)

この記事の例では、マウス切り替え画像を実現するためのjsの具体的なコードを参考までに共有しています。...

HTMLタグのtarget属性の使用法

1: <a> タグを使用してページにリンクする場合、target 属性の役割は誰もが知っ...

3 階層ナビゲーション メニューを実現するための js+css

この記事の例では、3レベルのナビゲーションメニューを実装するためのjs + cssの具体的なコードを...

Linux で NFS ファイル共有サーバーを構築するための詳細な手順

Linux が NFS サーバーを構築異なるオペレーティング システム間でデータを共有するために、通...

Webpack でよく使われる 12 個の Loader を共有する (要約)

目次序文スタイルローダーCSSローダーsassローダーpostcssローダーバベルローダーtsローダ...

jsを使用して簡単なスネークゲームを書く

この記事では、参考までに、jsで書かれたシンプルなスネークゲームの具体的なコードを紹介します。具体的...

Dockerのオンラインおよびオフラインインストールと一般的なコマンド操作

1. テスト環境名前バージョンセント7.6ドッカー18.09.06 2. オンラインインストールここ...

vue フロントエンド HbuliderEslint リアルタイム検証 自動修復設定

目次HBuilderX での ESLint プラグインのインストールカスタム eslint-js ル...

MySQL カーディナリティ統計の簡単な分析

1. カーディナリティとは何ですか?カーディナリティとは、MySQL テーブルの列内の異なる値の数を...

JS の new 関数の詳細な説明

目次1. 例2. 兵士100人を作成する3. 質問4. 改善点5. エレガント? 6. JSの父から...

mysql8.0.11をインストールしてrootパスワードを変更し、navicat for mysqlに接続するアイデアの詳細な説明

1.1. ダウンロード:公式ウェブサイトから zip パッケージをダウンロードします。私は 64 ビ...