nginx がその高性能、安定性、豊富な機能、シンプルな構成、低リソース消費で有名であることは誰もが知っていますが、なぜ nginx はそれほど速いのでしょうか?根本的な原理から分析してみましょう。
Nginx プロセス モデル
#Nginx サーバー、通常動作時:
複数のプロセス: 1 つのマスター プロセス、複数のワーカー プロセス。
マスタープロセス: ワーカープロセスを管理します。
外部インターフェイス: 外部操作 (シグナル) を受信します;
内部転送: さまざまな外部操作に応じてシグナルを通じてワーカーを管理します;
モニタリング: 実行中のワーカー プロセスを監視します状態にある場合、Worker プロセスが異常終了した後、Worker プロセスは自動的に再起動されます。
ワーカー プロセス: すべてのワーカー プロセスは同等です。
実際の処理: ネットワーク リクエストはワーカー プロセスによって処理されます。
ワーカー プロセスの数: nginx.conf で構成され、通常は CPU リソースを最大限に活用するためのコア数に設定されます。同時に、過度のプロセス数を回避し、CPU リソースの競合を回避します。そしてコンテキストスイッチングの損失が増加します。
考え:
リクエストは Nginx に接続されており、マスター プロセスが処理と転送を担当しますか?
リクエストを処理するワーカー プロセスを選択するにはどうすればよいですか?
リクエストの処理結果はマスタープロセスを通過する必要がありますか?
#HTTP 接続の確立とリクエスト処理のプロセスは次のとおりです。
Nginx が起動すると、マスター プロセスが設定ファイルを読み込みます。マスタープロセスは、リスニングソケットを初期化します。マスタープロセス、複数のワーカープロセスをフォークアウトします。ワーカー プロセスは新しい接続を求めて競合し、勝者は 3 ウェイ ハンドシェイクを通じてソケット接続を確立し、リクエストを処理します。
Nginx の高パフォーマンス、高同時実行性
なぜ Nginx は高いパフォーマンスを備え、高同時実行性をサポートしているのでしょうか?
Nginx は、マルチプロセス非同期ノンブロッキング モード (IO 多重化 Epoll) を採用しています。リクエストの完全なプロセス: リンクの確立 → リクエストの読み取り → リクエストの解析 → リクエストの処理 → リクエストへの応答。リクエストの完全なプロセスは、最下層のソケット イベントの読み取りと書き込みに対応します。
Nginx イベント処理モデル
リクエスト: Nginx の HTTP リクエスト。
基本的な HTTP Web サーバーの動作モード:
リクエストを受信します。リクエスト行とリクエストヘッダーを 1 行ずつ読み取り、セグメントにリクエストボディがあると判断した後、リクエストボディを読み取ります。リクエストを処理します。レスポンスを返す:処理結果に基づいて、対応するHTTPリクエスト(レスポンス行、レスポンスヘッダ、レスポンスボディ)を生成します。
Nginx もこのルーチンに従い、全体的なプロセスは同じです:
モジュラー アーキテクチャ
#Nginx モジュールは、その機能に応じて基本的に以下の種類に分類できます。
①イベントモジュール: OS に依存しないイベント処理機構の枠組みを構築し、特定のイベントの処理を提供します。 ngx_events_module、ngx_event_core_module、ngx_epoll_module などが含まれます。
Nginx がどのイベント処理モジュールを使用するかは、特定のオペレーティング システムとコンパイル オプションによって異なります。
②フェーズ ハンドラー: このタイプのモジュールは、直接ハンドラー モジュールとも呼ばれます。主に、クライアントのリクエストの処理と、応答するコンテンツの生成を担当します。ngx_http_static_module モジュールなど、クライアントの静的ページ リクエストの処理と、応答コンテンツの出力用に対応するディスク ファイルの準備を担当します。
③出力フィルター: フィルター モジュールとも呼ばれ、主に出力コンテンツの処理を担当し、出力を変更できます。
たとえば、すべての出力 HTML ページに定義済みのフットバーを追加したり、出力画像の URL を置き換えたりできます。
④upstream: 上流モジュールはリバース プロキシ機能を実装し、実際のリクエストをバックエンド サーバーに転送し、バックエンド サーバーからの応答を読み取り、クライアントに送り返します。
アップストリーム モジュールは特別な種類のハンドラーですが、応答コンテンツが実際にはそれ自体で生成されず、バックエンド サーバーから読み取られる点が異なります。
⑤ロードバランサー: 負荷分散モジュールは特定のアルゴリズムを実装し、多くのバックエンド サーバーの中から特定のリクエストの転送サーバーとしてサーバーを選択します。
一般的な問題の分析:
Nginx 対 Apache
Nginx:
IO 多重化、Epoll (freebsd 上の kqueue) 高いパフォーマンスと高い同時実行性 占有量が少ないシステム リソース
Apache:
マルチプロセス/マルチスレッドのブロックはより安定し、バグが少なく、モジュールが増えます
Nginx 最大接続数
基本的な背景 :
Nginx はマルチプロセス モデルであり、リクエストの処理にはワーカー プロセスが使用されます。単一プロセスの接続数 (ファイル記述子 fd) には上限 (nofile) があります: ulimit -n。 Nginx 上の単一ワーカー プロセスの最大接続数を構成します。worker_connections の上限は nofile です。 Nginx 上のワーカー プロセスの数を構成します:worker_processes。
したがって、Nginx の最大接続数:
Nginx の最大接続数: Worker プロセスの数 x 1 つの Worker プロセスの最大接続数。上記はNginxを一般サーバーとして使用する場合の最大接続数です。 Nginx がリバース プロキシ サーバーとして機能する場合、Nginx が提供できる接続の最大数: (ワーカー プロセスの数 x 単一のワーカー プロセスの最大接続数) / 2。 Nginx リバース プロキシを使用すると、クライアントへの接続とバックエンド Web サーバーへの接続が確立され、2 つの接続が占有されます。
考え:
Socket がオープンされるたびに、1 つの fd が占有されますか?プロセスが開くことができる FDS の数に制限があるのはなぜですか?
HTTP リクエストとレスポンス
HTTP リクエスト:
リクエスト行: メソッド、URI、http バージョンリクエストヘッダーリクエストボディ
HTTP レスポンス:
応答行: http バージョン、ステータス コード応答ヘッダー応答本文
IO モデル
複数の要求を処理する場合、次を使用できます: IO 多重化または IO マルチスレッドのブロック:
IO 多重化: 1 つのスレッドが複数のソケットのステータスを追跡し、準備ができたソケットが読み書きされます。 IO マルチスレッドのブロック: リクエストごとに、新しいサービス スレッドが作成されます。
IO 多重化とマルチスレッドに適用できるシナリオは何ですか?
IO 多重化: 単一接続のリクエスト処理速度には利点がありません。大規模な同時実行: 多数の同時リクエストの処理に 1 つのスレッドのみが使用されるため、コンテキスト切り替えの損失が軽減されます。同時実行の問題を考慮する必要はなく、比較的多くのリクエストを処理できます。消費するシステム リソースが少なくなります (スレッド スケジューリングのオーバーヘッドは必要ありません)。長時間の接続に適しています (マルチスレッド モードで長時間接続すると、スレッドが過剰になり、スケジュールが頻繁に発生する可能性があります)。 IO マルチスレッドのブロック: 実装が簡単で、システム コールに依存しません。各スレッドには時間とスペースが必要です。スレッドの数が増加すると、スレッド スケジューリングのオーバーヘッドが指数関数的に増加します。
select/poll と epoll の比較は次のとおりです。
select/poll システム コール:
// select 系统调用 int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout); // poll 系统调用 int poll(struct pollfd fds[], nfds_t nfds, int timeout);
select:
fd_set をクエリして確認します。準備ができた fd がある場合は、タイムアウト期間を設定し、 fd (ファイル記述子) が準備完了またはタイムアウトになったときに戻ることができます。 fd_set はビットセットで、サイズはカーネルのコンパイル時の定数で、デフォルトのサイズは 1024 です。特徴: 接続数が制限されており、fd_set が表すことができる fd の数が少なすぎます; リニア スキャン: fd の準備ができているかどうかを判断するには、fd_set の片側を走査する必要があります; データ コピー: ユーザー空間とカーネル空間、コピー接続準備ステータス情報。
poll:
接続制限を解決します。poll では、fd の数が少なすぎる問題を解決するために、select の fd_set を pollfd 配列に置き換えます。データ レプリケーション: ユーザー スペースとカーネル スペース、接続準備ステータス情報のコピー。
epoll、イベント イベント駆動型:
イベント メカニズム: リニア スキャンを回避し、各 fd のリッスン イベントを登録し、fd が Ready に変わったら、その fd を Ready リストに追加します。 fd の数: 制限なし (OS レベルの制限、単一プロセスでオープンできる fd の数)。
select、poll、epoll:
I/O 多重化メカニズム。 I/O 多重化では、複数のディスクリプタを監視するメカニズムが使用され、特定のディスクリプタの準備が完了すると (通常は読み取り準備完了または書き込み準備完了)、対応する読み取りおよび書き込み操作を実行するようにプログラムに通知でき、複数のファイルのディスクリプタを監視します。ただし、select、poll、および epoll は本質的に同期 I/O です。ユーザー プロセスは読み取りと書き込み (カーネル空間からユーザー空間へのコピー) を担当します。読み取りおよび書き込みプロセス中、ユーザー プロセスはブロックされますが、非同期 IO はブロックされません。ユーザー プロセスが読み取りと書き込みを担当する必要があり、非同期 IO はカーネル空間からユーザー空間へのコピーを担当します。
Nginx の同時処理能力
Nginx の同時処理能力について: 同時接続数は、最適化後、一般的にピーク値は 1 ~ 3w 程度を維持できます。 (メモリと CPU コアの数は異なります。さらに最適化の余地があります)
関連する推奨事項: nginx チュートリアル
以上がなぜnginxはそんなに速いのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。