I. Nginxの概要Nginxは、オープンソースで高性能、かつ信頼性の高いWebサーバーおよびリバースプロキシサーバーです。ホットデプロイメントをサポートし、ほぼ24時間365日、中断なく稼働できます。再起動を必要とせず、数ヶ月間稼働し続けることができ、サービスを中断することなくソフトウェアバージョンのホットアップデートも実行できます。パフォーマンスはNginxにとって最も重要な要素です。メモリ消費量が少なく、強力な同時実行能力を備え、最大50,000の同時接続をサポートできます。そして何より、Nginxは無料で商用利用も可能であり、設定と使用も比較的簡単です。 II. Nginxの機能- 高い同時実行性、高いパフォーマンス。
- モジュール型アーキテクチャにより、拡張性が非常に高くなります。
- 非同期で非ブロッキングのイベント駆動型モデルは Node.js のモデルに似ています。
- 他のサーバーと比較すると、再起動の必要がなく数か月以上連続稼働できるため、信頼性に優れています。
- ホットデプロイメントとスムーズなアップグレード。
- 完全にオープンソースで、活気のあるエコシステム。
III. Nginxの機能Nginx の最も重要な使用例: - 静的リソース サービスは、ローカル ファイル システムを通じて提供されます。
- リバース プロキシ サービスは、キャッシュ、負荷分散などにも拡張されます。
- API サービス、OpenResty。
フロントエンド開発者にとって、Node.jsは馴染みのある存在です。NginxとNode.jsは、HTTPサーバー、イベントドリブンアーキテクチャ、非同期ノンブロッキングメカニズムなど、多くの共通点を持っています。さらに、Nginxの機能のほとんどはNode.jsでも実装できます。しかし、NginxとNode.jsは競合するものではなく、それぞれに長所があります。Nginxは低レベルのサーバーサイドリソース(静的リソースの処理と転送、リバースプロキシ、負荷分散など)の処理に優れており、Node.jsは高レベルのビジネスロジックの処理に適しています。この2つは完璧に組み合わせることができます。 1 つの図で説明すると次のようになります。 IV. Nginxのインストールこの記事では、Linux CentOS 7.x オペレーティングシステムに Nginx をインストールする方法を説明します。他のオペレーティングシステムへのインストールについては、オンラインで検索できます。非常に簡単です。 yum を使用して Nginx をインストールします。 yum インストールnginx -y
インストール後、`rpm -ql nginx` コマンドを使用して Nginx のインストール情報を表示します。 /etc/nginx/nginx.conf /etc/nginx/nginx.conf.default /usr/bin/ nginx-アップグレード /usr/sbin/ nginx `/usr/lib/systemd/system/ nginx.service` 。 /usr/lib64/nginx/ modules
/usr/share/doc/ nginx-1 .16. 1 /usr/share/doc/ nginx-1 .16.1/ の変更点 /usr/share/doc/ nginx-1 .16.1/ README /usr/share/doc/ nginx-1 .16.1/ README.dynamic /usr/share/doc/ nginx-1 .16.1/ アップグレードノート-1 . 6 から 1 . 10 /usr/share/nginx/html/404.html /usr/share/nginx/html/50x.html /usr/share/nginx/html/index.html /var/log/ nginx
私が注目している主なフォルダーは 2 つあります。 - /etc/nginx/conf.d/ はサブ設定項目が保存される場所です。メイン設定ファイル /etc/nginx/nginx.conf は、デフォルトでこのフォルダ内のすべてのサブ設定項目をインポートします。
- 静的ファイルは /usr/share/nginx/html/ フォルダーに配置されますが、必要に応じて他の場所に配置することもできます。
V. よく使われるNginxコマンドsystemctl システムコマンド: systemctl enable nginx systemctl disable nginx
`systemctl start nginx` systemctl nginxを停止する
systemctl nginxを再起動します
systemctl nginxをリロードする
systemctl ステータスnginx ps -ef | grep nginx `kill -9 pid`
Nginx アプリケーション コマンド: `nginx -s reload` nginx -s reopen nginx -s stop nginx -s quit `nginx -T` nginx -t
VI. Nginxコアの設定6.1 設定ファイルの構造典型的な Nginx 構成の例: user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn ; pid /var/run/nginx.pid ; イベント{ use epoll; worker_connections 1024; }
http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"' ; access_log /var/log/nginx/access.log main ; sendfile on; tcp_nopush on; tcp_nodelayオン; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types ; default_type application/ octet-stream ; include /etc/nginx/conf.d/*.conf
- main: グローバル設定。グローバルに適用されます。
- events: Nginx サーバーとユーザー間のネットワーク接続に影響する構成。
- http: プロキシ、キャッシュ、ログ定義、サードパーティ モジュール構成などのほとんどの機能を構成します。
- server: 仮想ホストに関連するパラメータを設定します。HTTPブロック内に複数のserverブロックを含めることができます。
- location: 一致する URI を構成するために使用されます。
- アップストリーム: 負荷分散構成に不可欠なバックエンド サーバーの特定のアドレスを構成します。
その階層構造は、1 つの図で明確に示されます。 6.2 設定ファイルのメインセクションのコアパラメータ- user: Nginx を実行するワーカー子プロセスの所有者とグループを指定します。グループは省略可能です。
ユーザーユーザー名[グループ] user nginx lion ;
- pid: Nginx マスター プロセスの pid ファイルを保存するパスを指定します。
pid /opt/nginx/logs/nginx.pid # マスタープロセスの PID は nginx.pid ファイルに保存されます。 - worker_rlimit_nofile_number: ワーカー子プロセスが開くことができるファイル ハンドルの最大数を指定します。
worker_rlimit_nofile 20480;
- worker_rlimit_core: ワーカー子プロセスが異常終了した後の、問題の記録と分析に使用されるコア ファイルを指定します。
worker_rlimit_core 50M; working_directory /opt/nginx/tmp;
- worker_processes_number: Nginx によって開始されるワーカー子プロセスの数を指定します。
worker_processes 4; worker_processes auto;
- worker_cpu_affinity: 各ワーカー子プロセスを CPU 物理コアの 1 つにバインドします。
各ワーカー子プロセスを特定のCPU物理コアにバインドすると、同じワーカー子プロセスが異なるCPUコア間で切り替えられるのを防ぐことができ、キャッシュの無効化やパフォーマンスの低下を防ぐことができます。ただし、プロセス切り替えを完全に防ぐことはできません。 - worker_priority: ワーカー子プロセスのnice値を指定して、Nginxの実行優先度を調整します。通常は、Nginxの呼び出しを優先するため、負の値に設定されます。
worker_priority -10 ;
Linux のプロセスのデフォルトの優先度の値は 120 で、値が低いほど優先度が高くなります。nice 値は -20 から +19 の範囲で定義されています。 [注記] アプリケーションのデフォルトの優先度は、120 に nice 値を加算した値で、最終的な優先度となります。この値が小さいほど、優先度は高くなります。 - worker_shutdown_timeout: ワーカー子プロセスの正常なシャットダウンのタイムアウト期間を指定します。
ワーカーシャットダウンタイムアウト 5秒;
- timer_resolution: ワーカー子プロセスが内部的に使用するタイマーの精度。時間間隔が長いほどシステムコールの回数が少なくなり、パフォーマンスが向上します。逆に、システムコールの回数が増えるとパフォーマンスが低下します。
タイマー解像度100ms;
Linuxシステムでは、ユーザーがタイマーを取得する必要がある場合、オペレーティングシステムのカーネルにリクエストを送信する必要があります。リクエストごとにオーバーヘッドが発生するため、間隔が長いほどオーバーヘッドは小さくなります。 - daemon: Nginx の実行方法(フォアグラウンドまたはバックグラウンド)を指定します。フォアグラウンドはデバッグ用に使用され、バックグラウンドは本番環境で使用されます。
daemon off; # デフォルトではオンになっており、バックグラウンドで実行されます。 6.3 設定ファイルのイベントセクションのコアパラメータ- use: Nginx が使用するイベント駆動型モデル。
use method; `method`に指定できる値は、`select` 、`poll` 、`kqueue` 、`epoll` 、 `/dev/ poll`、および `eventport` です。
- worker_connections: ワーカー子プロセスが処理できる同時接続の最大数。
worker_connections 1024
- accept_mutex: 負荷分散ミューテックスを有効にするかどうか。
accept_mutex on
server_nameディレクティブ 仮想ホストのドメイン名を指定します。 サーバー名名前1 名前2 名前3 サーバー名www.nginx.com;
ドメイン名マッチングを記述する 4 つの方法: - 完全一致: server_name www.nginx.com;
- 左側のワイルドカード: server_name *.nginx.com;
- 右側のワイルドカード構成は次のとおりです: server_name www.nginx.* ;
- 正規表現の一致: server_name ~^www\.nginx\.*$ ;
一致の優先順位: 完全一致 > 左ワイルドカード一致 > 右ワイルドカード一致 > 正規表現一致。 server_name の設定例: 1) ローカルDNS解決を構成する: /etc/hostsを編集する (macOS) 121.42.11.34www.nginx-test.com 121.42.11.34mail.nginx-test.com 121.42.11.34www.nginx-test.org 121.42.11.34doc.nginx-test.com 121.42.11 . 34www.nginx-test.cn 121.42.11. 34 fe . nginx-test . クラブ
[注意] このテストでは仮想ドメイン名を使用しているため、ローカルDNS解決の設定が必要です。Alibaba Cloudから購入したドメイン名を使用している場合は、Alibaba Cloud上でドメイン名解決の設定を行う必要があります。 2) Alibaba Cloud Nginx を設定します。vim を使用して /etc/nginx/nginx.conf を編集します。 サーバー{ 80 を聞く; server_name * .nginx-test.com ; ルート/usr/share/nginx/html/ nginx-test / 左一致/; 位置/ { インデックスインデックス.html; } } サーバー{ 80 を聞く; server_name ~ ^ .* \ . nginx-test\ ..*$; ルート/usr/share/nginx/html/ nginx-test / reg-match /; 位置/ { インデックスインデックス.html; } } サーバー{ 80 を聞く; サーバー名www.nginx -test .*; ルート/usr/share/nginx/html/ nginx-test / 右一致/; 位置/ { インデックスインデックス.html; } } サーバー{ 80 を聞く; server_name www.nginx-test.com ; ルート/usr/share/nginx/html/ nginx-test / all-match /; 位置/ { インデックスインデックス.html; } }
3) アクセス分析 - www.nginx-test.com にアクセスすると、すべての結果が一致するため、最も優先度の高い「完全一致」が選択されます。
- mail.nginx-test.com にアクセスすると、「左一致」が実行されます。
- www.nginx-test.org にアクセスすると、「正しい一致」が実行されます。
- doc.nginx-test.com にアクセスすると、「左一致」が実行されます。
- www.nginx-test.cn にアクセスすると、「正しい一致」が実行されます。
- fe.nginx-test.club にアクセスすると、「正規表現マッチ」が実行されます。
根 http 、 server 、 location などの構成に書き込むことができる静的リソースディレクトリの場所を指定します。 ルートパス 例えば: 場所/ 画像{ ルート/opt/nginx/static; }
ユーザーがwww.test.com/image/1.pngにアクセスすると、サーバー上で見つかる実際のパスは/opt/nginx/static/image/1.pngです。 [注意] root は定義されたパスを URI と組み合わせますが、alias は定義されたパスのみを取得します。 エイリアス また、静的リソース ディレクトリの場所も指定します。これは、場所フィールドにのみ書き込むことができます。 場所/ 画像{ エイリアス/opt/nginx/static/image/; } ユーザーがwww.test.com/image/1.png にアクセスすると、 サーバー上で見つかる実際のパスは/opt/nginx/static/image/1.png です。
[注意] エイリアスを使用する場合は、末尾にスラッシュ (/) を追加する必要があり、ロケーション内でのみ使用できます。 位置 パスを設定します。 場所[ = | ~ | ~ * | ^ ~ ] uri { ... }
マッチングルール: - = 完全一致;
- ~ 正規表現マッチング、大文字と小文字を区別します。
- ~* 正規表現マッチング、大文字と小文字を区別しません。
- ^~ 一致が見つかると検索は停止します。
一致の優先順位: = > ^~ > ~ > ~* > 文字なし。 例: サーバー{ 80 を聞く; server_name www.nginx-test.com ; 場所= /match_all/ { ルート/usr/share/nginx/ html インデックスindex.html } 場所~ \ . (jpeg |jpg |png |svg ) $ { ルート/usr/share/nginx/images; } 場所^ ~ /bbs/ { ルート/usr/share/nginx/html; インデックスインデックス.html インデックス.htm; } }
1) 場所を示すバックスラッシュ 場所/ テスト{ ... } 場所/test/ { ... }
- スラッシュ「/」がない場合、www.nginx-test.com/test にアクセスすると、Nginx はまず「test」ディレクトリが存在するかどうかを確認します。存在する場合、そのディレクトリ内の index.html ファイルを探します。「test」ディレクトリが存在しない場合、Nginx は次に「test」という名前のファイルを探します。
- www.nginx-test.com/test にアクセスすると、Nginx はまずテストディレクトリが存在するかどうかを確認します。存在する場合は、そのディレクトリ内の index.html ファイルを探します。存在しない場合は、テストファイルの存在確認は行われません。
2) 戻る リクエストの処理を停止し、応答コードを直接返すか、別の URL にリダイレクトします。 return ディレクティブを実行した後、location ブロック内の後続のディレクティブは実行されません。 戻りコード[テキスト]; 戻りコード URL ; URL を返します。 例えば: 位置/ { return 404; } 位置/ { return 404 "pages not found" ; } 位置/ { return 302 / bbs ; } 位置/ { return https://www.baidu.com ; }
リライト 指定された正規表現の一致ルールに基づいて URL を書き換えます。 オプションのフラグ値の意味: 構文: ` 正規表現を書き換える[ フラグ] ` ; コンテキスト: サーバー、場所、if 例: `rewrite /images/ ( .* \ . jpg) $ /pic/$1;
オプションのフラグ値の意味: - 最後の URL は新しいリクエストを開始するために使用され、サーバー セグメントに再度入り、場所の一致を再試行します。
- `break` ステートメントは書き換えられた URL を直接使用するため、他の `location` ブロック内のステートメントと一致しなくなります。
- リダイレクトは 302 一時リダイレクトを返します。
- permanent オプションは 301 永続リダイレクトを返します。
サーバー{ 80 を聞く; server_name fe.lion.club; ルートhtml; 場所/ 検索{ 書き換え^ / ( .* ) https://www.baidu.com リダイレクト; } 場所/ 画像{ /images/ ( .* ) /pics/$1 を書き換えます。 } 場所/ 写真{ /pics/ ( .* ) /photos/$1 を書き換えます。 } 場所/ 写真{ } }
この構成を分析してみましょう。 - fe.lion.club/search にアクセスすると、自動的に https://www.baidu.com にリダイレクトされます。
- fe.lion.club/images/1.jpg にアクセスする場合、まず URL を fe.lion.club/pics/1.jpg に書き換え、pics の場所を見つけ、次に URL を fe.lion.club/photos/1.jpg に書き換えます。/photos の場所を見つけた後、html/photos ディレクトリ内の静的リソース 1.jpg を探します。
指示の場合 構文: if (条件) {...} コンテキスト: サーバー、場所 例: if ( $http_user_agent ~ Chrome) { 書き換え/ ( .* ) /browser/ $1 break ; }
状態: - $variable を変数として使用すると、空の値または 0 で始まる文字列は false として扱われます。
- = または != は等しいか等しくないかを意味します。
- ~ 正規表現マッチング;
- ! ~ 非正規表現マッチング;
- ~* 正規表現マッチング、大文字と小文字を区別しません。
- -f または ! -f はファイルが存在するかどうかを確認します。
- -d または ! -d はディレクトリが存在するかどうかを確認します。
- -e または ! -e は、ファイル、ディレクトリ、シンボリック リンクなどが存在するかどうかを確認します。
- -x または ! -x はファイルが実行可能かどうかを確認します。
例: サーバー{ 8080 を聴く; server_nameローカルホスト; ルートhtml; 位置/ { $ uriが"/images/" の場合 書き換え( .* ) /pics/ break ; } } }
localhost:8080/images/ にアクセスすると、if ステートメント内で rewrite コマンドが実行されます。 自動インデックス ユーザーリクエストがスラッシュ (/) で終わる場合、ディレクトリ構造がリストされ、静的リソースダウンロード Web サイトをすばやく構築できます。 autoindex.conf 構成情報: サーバー{ 80 を聞く; server_name fe.lion-test.club ; 場所/download/ { ルート/opt/source; autoindex on; `autoindex_exact_size on; autoindex_format html ; autoindex_localtime off; } }
fe.lion.com/download/ にアクセスすると、以下の画像のように、サーバー上のパス /opt/source/download/ の下にあるファイルが表示されます。 6.4 変数Nginxはユーザーに多数の変数を提供しますが、最終的にはリクエストプロセス全体によって生成されるデータセットです。Nginxはこれらのデータを変数の形でユーザーに提供します。 プロジェクトでよく使用される変数は次のとおりです。 var.confの例: サーバー{ 8081 を聴く; server_name var. lion-test .club; ルート/usr/share/nginx/html; 位置/ { 200 を返す リモートアドレス: $remote_addr リモートポート: $remote_port サーバーアドレス: $server_addr サーバーポート: $server_port サーバープロトコル: $server_protocol バイナリリモートアドレス: $バイナリリモートアドレス 接続: $connection uri: $uri リクエストURI: $request_uri スキーム: $scheme リクエストメソッド: $request_method リクエスト長: $request_length 引数: $args arg_pid: $arg_pid is_args: $is_args クエリ文字列: $クエリ文字列 ホスト: $host http_user_agent: $http_user_agent http_referer: $http_referer http_via: $http_via リクエスト時間: $request_time https: $https リクエストファイル名: $request_filename ドキュメントルート: $document_root 「 } }
Docker、Kubernetes、Jenkins などの主流のテクノロジーに関する包括的なビデオ チュートリアル。 http://var.lion-test.club:8081/test?pid=121414&cid=sadasd にアクセスすると、Nginx には `return` メソッドがあるため、Chrome はデフォルトでファイルをダウンロードします。ダウンロードされたファイルの内容は次のとおりです。 リモートアドレス: 27.16.220.84 リモートポート: 56838 サーバーアドレス: 172.17.0.2 サーバーポート: 8081 サーバープロトコル: HTTP/ 1.1 バイナリリモートアドレス: 接続: 126 URI: /テスト/ リクエストURI: /test/ ?pid = 121414&cid = sadasd スキーム: http リクエストメソッド: GET リクエスト長: 518 引数: pid = 121414&cid = sadasd 引数pid: 121414 is_args: ? クエリ文字列: pid = 121414&cid = sadasd ホスト: var.lion-test.club http_user_agent : Mozilla / 5. 0 ( Macintosh ; Intel Mac OS http_referer: http_via: リクエスト時間: 0.000 https: リクエストファイル名: /usr/share/nginx/html/test/ ドキュメントルート: /usr/share/nginx/ html
Nginxには他にも多くの設定方法があります。上記はよく使われる設定の一部です。実際のプロジェクトでは、ドキュメントを参照する方法を学ぶ必要があります。 VII. Nginxアプリケーションのコアコンセプトプロキシは、サーバーとクライアントの間に位置づけられるサーバー層です。プロキシはクライアントからのリクエストを受信してサーバーに転送し、サーバーのレスポンスをクライアントに転送します。 フォワード プロキシでもリバース プロキシでも、同じ機能が実現されます。 7.1 フォワードプロキシフォワードプロキシは、クライアントとオリジンサーバーの間に位置するサーバーです。クライアントはオリジンサーバーからコンテンツを取得するために、プロキシにリクエストを送信し、ターゲット(オリジンサーバー)を指定します。プロキシはリクエストをオリジンサーバーに転送し、取得したコンテンツをクライアントに返します。 フォワードプロキシは、私たち、つまりクライアントにサービスを提供します。クライアントは、フォワードプロキシを介して、自身ではアクセスできないサーバーリソースにアクセスできます。 フォワード プロキシは、私たちにとっては透過的ですが、サーバーにとっては透過的ではありません。つまり、サーバーは、アクセスをプロキシから受け取っているのか、実際のクライアントから受け取っているのかを知りません。 7.2 リバースプロキシリバースプロキシとは、インターネットからの接続要求を受け付け、内部ネットワーク上のサーバーに転送し、サーバーからの接続結果をインターネット上で接続を要求したクライアントに返すプロキシサーバーです。この場合、プロキシサーバーは外部からはリバースプロキシサーバーのように見えます。 リバースプロキシはサーバーにサービスを提供します。リバースプロキシは、サーバーがクライアントからのリクエストを受信し、リクエストを転送し、負荷分散を行うのに役立ちます。 リバース プロキシはサーバーに対しては透過的ですが、ユーザーに対しては透過的ではありません。つまり、ユーザーはプロキシ サーバーにアクセスしていることに気付きませんが、サーバーはリバース プロキシがサービスを提供していることを認識しています。 リバースプロキシの利点: - 実際のサーバーを隠す;
- 負荷分散により、バックエンドの動的サービスの水平スケーリングが容易になります。
- 静的状態と動的状態を分離すると、システムの堅牢性が向上します。
では、「静的コンテンツと動的コンテンツの分離」とは何でしょうか?また、負荷分散とは何でしょうか? 7.3 静的状態と動的状態の分離静的コンテンツと動的コンテンツの分離とは、Web サーバー アーキテクチャにおけるアーキテクチャ設計方法の 1 つであり、異なるシステムからのアクセスのために静的ページと動的ページ、または静的コンテンツ インターフェイスと動的コンテンツ インターフェイスを分離することで、サービス全体のアクセシビリティと保守性を向上させます。 一般的に、動的リソースと静的リソースは分離する必要があります。Nginxは高い同時実行性と静的リソースのキャッシュ機能を備えているため、静的リソースはNginx上にデプロイされることが多くなっています。静的リソースが要求された場合、静的リソースディレクトリから直接取得されます。動的リソースが要求された場合、リクエストはリバースプロキシの原理に基づいて対応するバックエンドアプリケーションに転送され、処理されます。これにより、静的リソースと動的リソースの分離が実現されます。 フロントエンドとバックエンドを分離するアプローチを使用すると、静的リソースへのアクセス速度が大幅に向上し、動的サービスが利用できない場合でも、静的リソースへのアクセスは影響を受けません。 7.4 負荷分散通常、クライアントはサーバーに複数のリクエストを送信し、サーバーはそれらのリクエストを処理します。これらのリクエストの中には、データベースや静的リソースなどのリソースに対する操作が含まれる場合があります。サーバーは処理を完了すると、結果をクライアントに返します。 このモデルは、機能要件が単純で同時リクエスト数が比較的少ない初期のシステムには十分であり、コストも低かった。しかし、情報量、アクセス量、データ量が急増し、システム業務の複雑化が進むにつれて、このアプローチでは要件を満たすことができなくなった。特に同時リクエスト数が多い場合、サーバーがクラッシュしやすくなった。 この問題はサーバーパフォーマンスのボトルネックによって引き起こされていることは明らかです。マシンの追加に加えて、最も重要なのは負荷分散です。 リクエストが急増すると、たとえ最も高性能なマシン単体でも需要に対応できなくなります。そこでクラスタの概念が登場します。単一のサーバーでは解決できない問題は、複数のサーバーを活用し、リクエストを分散させることで、負荷を複数のサーバーに分散させることで解決できます。これがロードバランシングであり、その基本原則は「負荷を分散すること」です。Nginxは、リクエストをサーバークラスタに転送することでロードバランシングを実現します。 具体的な例を挙げると、夕方のラッシュアワー時に地下鉄を利用する際、駅員が入口のスピーカーで「B出口をご利用ください。B出口は空いており、電車も空いています…」とアナウンスすることがよくあります。こうした駅員の役割は、負荷のバランスを取ることです。 Nginx の負荷分散戦略: - ラウンドロビン戦略:これはデフォルトの戦略で、すべてのクライアントリクエストをラウンドロビン方式でサーバーに分散します。この戦略は通常は機能しますが、1台のサーバーに過度の負荷と遅延が発生すると、そのサーバーに割り当てられているすべてのユーザーに影響を及ぼします。
- 最小接続戦略では、負荷の低いサーバーへのリクエストの分散を優先します。これにより、各キューの長さが均衡し、負荷の高いサーバーへのリクエストの追加を回避します。
- 最速応答時間戦略: 応答時間が最も短いサーバーへの割り当てを優先します。
- クライアント IP バインディング戦略: 同じ IP からのリクエストは常に 1 つのサーバーにのみ割り当てられるため、動的な Web ページに存在するセッション共有の問題が効果的に解決されます。
8. 実用的なNginxの設定リバースプロキシやロードバランシングなどの機能を設定する前に、習得しなければならない2つのコアモジュールがあります。これら2つのモジュールは、Nginxアプリケーション設定の中核と言えるでしょう。upstreamとproxy_passです。 8.1アップストリームこれは、アップストリーム サーバー (バックグラウンドで提供されるアプリケーション サーバーを指します) に関連する情報を定義するために使用されます。 構文: アップストリーム名{ ... } コンテキスト: http 例: アップストリームバックエンドサーバー{ サーバー192.168.100.33: 8081 }
アップストリーム内で使用できるコマンド: - `server` パラメータはアップストリーム サーバーのアドレスを定義します。
- ゾーンは、ワーカーの子プロセス全体で使用される共有メモリを定義します。
- keepalive はアップストリーム サービスへの永続的な接続を可能にします。
- keepalive_requests: 単一の長時間接続で実行できる HTTP リクエストの最大数。
- keepalive_timeout は、アイドル期間中の長時間接続のタイムアウト期間です。
- ハッシュ負荷分散アルゴリズム。
- ip_hash は、IP アドレスに基づいてハッシュ計算を実行する負荷分散アルゴリズムです。
- least_conn は、最小接続の負荷分散アルゴリズムです。
- least_time は、応答時間が最短の負荷分散アルゴリズムです。
- ランダム負荷分散アルゴリズム。
サーバ アップストリーム サーバーのアドレスを定義します。 構文: サーバーアドレス[パラメータ] コンテキスト: 上流
パラメータには次の値を指定できます。 - weight=number 重みの値、デフォルトは 1。
- max_conns=number アップストリーム サーバーへの同時接続の最大数。
- fail_timeout = 時間、サーバーが利用できないと見なされる時間を示します。
- max_fails = サーバーが利用不可かどうかチェックされた回数。
- バックアップ サーバーは、他のすべてのサーバーが使用できない場合にのみ有効になります。
- 「ダウン」フラグは、サーバーが長期間使用できず、オフラインメンテナンスが行われていることを示します。
キープアライブ 各ワーカー子プロセスとアップストリーム サーバー間のアイドル状態の長期接続の最大数を制限します。 キープアライブ接続; 次のテキスト:上流 例: keepalive 16;
キープアライブリクエスト 単一の長時間接続で処理できる HTTP リクエストの最大数。 構文: keepalive_requests number; デフォルト値: keepalive_requests 100; コンテキスト: 上流
キープアライブタイムアウト アイドル状態の長時間接続の最長保持時間。 構文: keepalive_timeout time; デフォルト値: keepalive_timeout 60秒; コンテキスト: 上流
設定例 構文: keepalive_timeout time; デフォルト値: keepalive_timeout 60秒; コンテキスト: 上流
8.2 プロキシパスプロキシ サーバーを構成するために使用されます。 構文: proxy_pass URL; コンテキスト: location 、if 、limit_except 例: プロキシパスhttp://127.0.0.1 : 8081 proxy_pass http://127.0.0.1:8081/ プロキシ
URLパラメータの原則: - URL は http または https で始まる必要があります。
- URL には変数を含めることができます。
- URL に URI が含まれているかどうかは、アップストリーム リクエストに送信される URL に直接影響します。
次に、2 つの一般的な URL の使用法を見てみましょう。 - プロキシパス http://192.168.100.33:8081
- プロキシパス http://192.168.100.33:8081/
これら 2 つの使用法の違いはスラッシュ (/) の有無であり、プロキシを構成するときに大きな違いが生じます。 - スラッシュがない場合、Nginx はユーザーの URL を変更せず、それをアップストリーム アプリケーション サーバーに直接渡します。
- スラッシュ (/) は、Nginx がユーザーの URL からロケーション ブロックの後の URL を削除してユーザーの URL を変更することを意味します。
スラッシュなしの使用法: 場所/bbs/{ プロキシパスhttp://127.0.0.1:8080 ; }
分析: - ユーザーが要求した URL: /bbs/abc/test.html
- リクエストはNginx URLに到達しました: /bbs/abc/test.html
- リクエストは上流アプリケーションサーバーの URL: /bbs/abc/test.html に到達しました
/の使い方: 場所/bbs/{ プロキシパスhttp://127.0.0.1:8080/ ; }
分析: - ユーザーが要求した URL: /bbs/abc/test.html
- リクエストはNginx URLに到達しました: /bbs/abc/test.html
- リクエストは、URL: /abc/test.html の上流アプリケーション サーバーに到達しました。
/bbs 拡張子は追加されませんでした。これは、ルートとエイリアスの違いと一致しています。 8.3 リバースプロキシの設定デモンストレーションをより現実的にするために、著者はパブリック IP がそれぞれ 121.42.11.34 と 121.5.180.193 である 2 台のクラウド サーバーを用意しました。 サーバー 121.42.11.34 をアップストリーム サーバーとして使用し、次のように構成します。 サーバー{ 8080 を聴く; server_nameローカルホスト; 場所/ プロキシ/ { ルート/usr/share/nginx/html/ プロキシ; インデックスインデックス.html; } } <h1 > 121.42.11. 34 プロキシHTML < /h1>
設定後、Nginx サーバーを再起動します: nginx -s reload。 次のように、121.5.180.193 サーバーをプロキシ サーバーとして構成します。 アップストリームバックエンド{ サーバー121.42.11.34: 8080 重み= 2 max_conns = 1000 fail_timeout = 10s max_fails =3; キープアライブ 32 ; キープアライブリクエスト80; keepalive_timeout 20秒; } サーバー{ 80 を聞く; サーバー名proxy.lion.club ; 場所/ プロキシ{ proxy_pass http ://back_end/ プロキシ; } }
本地机器要访问proxy.lion.club 域名,因此需要配置本地hosts ,通过命令:vim /etc/hosts 进入配置文件,添加如下内容: 121.5.180. 193 proxy .lion. club
分析: - 当访问proxy.lion.club/proxy 时通过upstream 的配置找到121.42.11.34:8080 ;
- 因此访问地址变为http://121.42.11.34:8080/proxy ;
- 连接到121.42.11.34 服务器,找到8080 端口提供的server ;
- 通过server 找到/usr/share/nginx/html/proxy/index.html 资源,最终展示出来。
8.4 配置负载均衡配置负载均衡主要是要使用upstream 指令。 我们把121.42.11.34 服务器作为上游服务器,做如下配置( /etc/nginx/conf.d/balance.conf ): サーバー{ listen 8020; 位置/ { return 200 'return 8020 \n' ; } } サーバー{ listen 8030; 位置/ { return 200 'return 8030 \n' ; } } サーバー{ listen 8040; 位置/ { return 200 'return 8040 \n' ; } }
配置完成后: - nginx -t 检测配置是否正确;
- nginx -s reload 重启Nginx 服务器;
- 执行ss -nlt 命令查看端口是否被占用,从而判断Nginx 服务是否正确启动。
把121.5.180.193 服务器作为代理服务器,做如下配置( /etc/nginx/conf.d/balance.conf ): upstream demo_server { server 121.42.11.34:8020; server 121.42.11.34:8030; server 121.42.11.34:8040; } サーバー{ 80 を聞く; server_name balance.lion.club; location /balance/ { proxy_pass http ://demo_server; } }
配置完成后重启Nginx 服务器。并且在需要访问的客户端配置好IP 和域名的映射关系。 121.5.180. 193 balance .lion. club
在客户端机器执行curl http://balance.lion.club/balance/ 命令: 不难看出,负载均衡的配置已经生效了,每次给我们分发的上游服务器都不一样。就是通过简单的轮询策略进行上游服务器分发。 接下来,我们再来了解下Nginx 的其它分发策略。 hash 算法 通过制定关键字作为hash key ,基于hash 算法映射到特定的上游服务器中。关键字可以包含有变量、字符串。 upstream demo_server { hash $request_uri; server 121.42.11.34:8020; server 121.42.11.34:8030; server 121.42.11.34:8040; } サーバー{ 80 を聞く; server_name balance.lion.club; location /balance/ { proxy_pass http ://demo_server; } }
hash $request_uri 表示使用request_uri 变量作为hash 的key 值,只要访问的URI 保持不变,就会一直分发给同一台服务器。 ip_hash 根据客户端的请求IP 进行判断,只要IP 地址不变就永远分配到同一台主机。它可以有效解决后台服务器session 保持的问题。 upstream demo_server { ip_hash ; server 121.42.11.34:8020; server 121.42.11.34:8030; server 121.42.11.34:8040; } サーバー{ 80 を聞く; server_name balance.lion.club; location /balance/ { proxy_pass http ://demo_server; } }
最少连接数算法 各个worker 子进程通过读取共享内存的数据,来获取后端服务器的信息。来挑选一台当前已建立连接数最少的服务器进行分配请求。 语法:least_conn ; 上下文:upstream ;
例: upstream demo_server { zone test 10M; least_conn; server 121.42.11.34:8020; server 121.42.11.34:8030; server 121.42.11.34:8040; } サーバー{ 80 を聞く; server_name balance.lion.club; location /balance/ { proxy_pass http ://demo_server; } }
最后你会发现,负载均衡的配置其实一点都不复杂。 8.5 配置缓存缓存可以非常有效的提升性能,因此不论是客户端(浏览器),还是代理服务器( Nginx ),乃至上游服务器都多少会涉及到缓存。可见缓存在每个环节都是非常重要的。下面让我们来学习Nginx 中如何设置缓存策略。 proxy_cache 存储一些之前被访问过、而且可能将要被再次访问的资源,使用户可以直接从代理服务器获得,从而减少上游服务器的压力,加快整个访问速度。 语法:proxy_cache zone | off ; 默认值:proxy_cache off; 上下文:http 、server 、location
proxy_cache_path 设置缓存文件的存放路径。 语法:proxy_cache_path path [level=levels] ... 可选参数省略, 下面会详细列举 默认值:proxy_cache_path off 上下文:http
パラメータの意味: - path 缓存文件的存放路径;
- level path 的目录层级;
- keys_zone 设置共享内存;
- inactive 在指定时间内没有被访问,缓存会被清理,默认10分钟。
proxy_cache_key 设置缓存文件的key 。 语法:proxy_cache_key 默认值:proxy_cache_key $scheme$proxy_host$request_uri; 上下文:http 、server 、location
proxy_cache_valid 配置什么状态码可以被缓存,以及缓存时长。 语法:proxy_cache_valid [code...] time; 上下文:http 、server 、location 配置示例:proxy_cache_valid 200 304 2m;;
proxy_no_cache 定义相应保存到缓存的条件,如果字符串参数的至少一个值不为空且不等于“ 0”,则将不保存该响应到缓存。 语法:proxy_no_cache string; 上下文:http 、server 、location 示例:proxy_no_cache $http_pragma $http_authorization;
proxy_cache_bypass 定义条件,在该条件下将不会从缓存中获取响应。 语法:proxy_cache_bypass string; 上下文:http 、server 、location 示例:proxy_cache_bypass $http_pragma $http_authorization;
upstream_cache_status 变量 它存储了缓存是否命中的信息,会设置在响应头信息中,在调试中非常有用。 MISS: 未命中缓存 HIT: 命中缓存 EXPIRED: 缓存过期 STALE: 命中了陈旧缓存 REVALIDDATED: Nginx验证陈旧缓存依然有效 UPDATING: 内容陈旧, 但正在更新 BYPASS: X响应从原始服务器获取
配置实例 我们把121.42.11.34 服务器作为上游服务器,做如下配置( /etc/nginx/conf.d/cache.conf ): サーバー{ listen 1010; root /usr/share/nginx/html/1010; 位置/ { index index .html; } } サーバー{ listen 1020; root /usr/share/nginx/html/1020; 位置/ { index index .html; } }
把121.5.180.193 服务器作为代理服务器,做如下配置( /etc/nginx/conf.d/cache.conf ): proxy_cache_path /etc/nginx/ cache_temp levels =2: 2 keys_zone =cache_zone: 30m max_size = 2g inactive = 60m use_temp_path =off; upstream cache_server{ server 121.42.11.34:1010; server 121.42.11.34:1020; } サーバー{ 80 を聞く; server_name cache.lion.club; 位置/ { proxy_cache cache_zone; proxy_cache_valid 200 5m ; proxy_cache_key $request_uri; add_header Nginx-Cache-Status $upstream_cache_status proxy_pass http ://cache_server; } }
缓存就是这样配置,我们可以在/etc/nginx/cache_temp 路径下找到相应的缓存文件。 对于一些实时性要求非常高的页面或数据来说,就不应该去设置缓存,下面来看看如何配置不缓存的内容。 ... サーバー{ 80 を聞く; server_name cache.lion.club; i ( $request_uri ~ \ . (txt |text ) $) { set $cache_name "no cache" } 位置/ { proxy_no_cache $cache_name; proxy_cache cache_zone; proxy_cache_valid 200 5m ; proxy_cache_key $request_uri; add_header Nginx-Cache-Status $upstream_cache_status proxy_pass http ://cache_server; } }
8.6 HTTPS在学习如何配置HTTPS 之前,我们先来简单回顾下HTTPS 的工作流程是怎么样的?它是如何进行加密保证安全的? HTTPS 工作流程 - 客户端(浏览器)访问https://www.baidu.com 百度网站;
- 百度服务器返回HTTPS 使用的CA 证书;
- 浏览器验证CA 证书是否为合法证书;
- 验证通过,证书合法,生成一串随机数并使用公钥(证书中提供的)进行加密;
- 发送公钥加密后的随机数给百度服务器;
- 百度服务器拿到密文,通过私钥进行解密,获取到随机数(公钥加密,私钥解密,反之也可以);
- 百度服务器把要发送给浏览器的内容,使用随机数进行加密后传输给浏览器;
- 此时浏览器可以使用随机数进行解密,获取到服务器的真实传输内容;
这就是HTTPS 的基本运作原理,使用对称加密和非对称机密配合使用,保证传输内容的安全性。 配置证书 下载证书的压缩文件,里面有个Nginx 文件夹,把xxx.crt 和xxx.key 文件拷贝到服务器目录,再进行如下配置: サーバー{ listen 443 ssl http2 default_server ; server_name lion.club; ssl_certificate /etc/nginx/https/lion.club_bundle.crt; ssl_certificate_key /etc/nginx/https/lion.club.key; ssl_session_timeout 10m; ssl_protocols TLSv1 TLSv1 . 1 TLSv1 .2; 位置/ { root /usr/share/nginx/html; index index . html index .htm; } }
如此配置后就能正常访问HTTPS 版的网站了。 8.7 配置跨域CORS先简单回顾下跨域究竟是怎么回事。 跨域的定义 同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。通常不允许不同源间的读操作。 同源的定义 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。 下面给出了与URL http://store.company.com/dir/page.html 的源进行对比的示例: http ://store.company.com/dir2/other. html 同源 https://store.company.com/secure. html 不同源, 协议不同 http ://store.company.com:81/dir/etc. html 不同源, 端口不同 http ://news.company.com/dir/other. html 不同源, 主机不同
不同源会有如下限制: - Web 数据层面,同源策略限制了不同源的站点读取当前站点的Cookie 、 IndexDB 、 LocalStorage 等数据;
- DOM 层面,同源策略限制了来自不同源的JavaScript 脚本对当前DOM 对象读和写的操作;
- 网络层面,同源策略限制了通过XMLHttpRequest 等方式将站点的数据发送给不同源的站点。
Nginx 解决跨域的原理 例えば: - 前端server 的域名为:fe.server.com
- 后端服务的域名为:dev.server.com
现在我在fe.server.com 对dev.server.com 发起请求一定会出现跨域。 现在我们只需要启动一个Nginx 服务器,将server_name 设置为fe.server.com 然后设置相应的location 以拦截前端需要跨域的请求,最后将请求代理回dev.server.com 。如下面的配置: サーバー{ 80 を聞く; server_name fe. server .com; loation / { proxy_pass dev. server .com; } }
这样可以完美绕过浏览器的同源策略:fe.server.com 访问Nginx 的fe.server.com 属于同源访问,而Nginx 对服务端转发的请求不会触发浏览器的同源策略。 8.8 配置开启gzip 压缩GZIP 是规定的三种标准HTTP 压缩格式之一。目前绝大多数的网站都在使用GZIP 传输HTML 、CSS 、 JavaScript 等资源文件。 对于文本文件, GZiP 的效果非常明显,开启后传输所需流量大约会降至1/4~1/3 。 并不是每个浏览器都支持gzip 的,如何知道客户端是否支持gzip 呢,请求头中的Accept-Encoding 来标识对压缩的支持。 启用gzip 同时需要客户端和服务端的支持,如果客户端支持gzip 的解析,那么只要服务端能够返回gzip 的文件就可以启用gzip 了,我们可以通过Nginx 的配置来让服务端支持gzip 。下面的respone 中content-encoding:gzip ,指服务端开启了gzip 的压缩方式。 在/etc/nginx/conf.d/ 文件夹中新建配置文件gzip.conf : gzip on; gzip_types text/ plain text / css application / json application / x-javascript text/ xml application / xml application /xml+ rss text /javascript; gzip_static on; gzip_proxied any; gzip_varyオン; gzip_comp_level 6; gzip_buffers 16 8k ; gzip_http_version 1.1;
其实也可以通过前端构建工具例如webpack 、rollup 等在打生产包时就做好Gzip 压缩,然后放到Nginx 服务器中,这样可以减少服务器的开销,加快访问速度。 关于Nginx 的实际应用就学习到这里,相信通过掌握了Nginx 核心配置以及实战配置,之后再遇到什么需求,我们也能轻松应对。接下来,让我们再深入一点学习下Nginx 的架构。 九. Nginx 架构9.1 进程结构多进程结构Nginx 的进程模型图: 多进程中的Nginx 进程架构如下图所示,会有一个父进程( Master Process ),它会有很多子进程( Child Processes )。 - Master Process 用来管理子进程的,其本身并不真正处理用户请求。
- 某个子进程down 掉的话,它会向Master 进程发送一条消息,表明自己不可用了,此时Master 进程会去新起一个子进程;
- 某个配置文件被修改了Master 进程会去通知work 进程获取新的配置信息,这也就是我们所说的热部署。
9.2 配置文件重载原理reload 重载配置文件的流程: - 向master 进程发送HUP 信号( reload 命令);
- master 进程检查配置语法是否正确;
- master 进程打开监听端口;
- master 进程使用新的配置文件启动新的worker 子进程;
- master 进程向老的worker 子进程发送QUIT 信号;
- 老的worker 进程关闭监听句柄,处理完当前连接后关闭进程;
- 整个过程Nginx 始终处于平稳运行中,实现了平滑升级,用户无感知。
9.3 Nginx 模块化管理机制Nginx 的内部结构是由核心部分和一系列的功能模块所组成。这样划分是为了使得每个模块的功能相对简单,便于开发,同时也便于对系统进行功能扩展。Nginx 的模块是互相独立的,低耦合高内聚。 要約相信通过本文的学习,你应该会对Nginx 有一个更加全面的认识。 |