ホームページ  >  記事  >  バックエンド開発  >  nginxの接続概念

nginxの接続概念

WBOY
WBOYオリジナル
2016-08-08 09:21:021065ブラウズ
nginx では、接続は、接続されたソケット、読み取りイベント、書き込みイベントを含む tcp 接続のカプセル化です。 nginx でカプセル化された接続を使用すると、接続の確立、データの送受信など、接続関連の問題を nginx で簡単に処理できます。 nginx での http リクエストの処理は接続に基づいているため、nginx は Web サーバーとしてだけでなく、メール サーバーとしても使用できます。もちろん、nginx が提供する接続を使用して、あらゆるバックエンド サービスを処理できます。 TCP 接続のライフサイクルと組み合わせて、nginx が接続をどのように処理するかを見てみましょう。まず、nginx が起動すると、設定ファイルを解析して監視する必要があるポートと IP アドレスを取得します。次に、nginx マスター プロセスで、最初に監視ソケットを初期化します (ソケットを作成し、addrreuse およびその他のオプションを設定し、バインドします)。指定された IP アドレス ポートを使用してリッスン)、複数の子プロセスをフォークアウトすると、子プロセスが新しい接続を受け入れるために競合します。この時点で、クライアントは nginx への接続を開始できます。クライアントとサーバーが 3 ウェイ ハンドシェイクを通じて接続を確立すると、nginx のサブプロセスが正常に受け入れ、確立された接続のソケットを取得して、nginx による接続のカプセル化、つまり ngx_connection_t 構造を作成します。次に、読み取りおよび書き込みイベント処理関数を設定し、クライアントとデータを交換するための読み取りおよび書き込みイベントを追加します。最後に、nginx またはクライアントが接続をアクティブに閉じます。この時点で、接続は終了します。 もちろん、nginx は他のサーバー (アップストリーム モジュールなど) にデータを要求するクライアントとしても使用できます。このとき、他のサーバーと作成された接続も ngx_connection_t にカプセル化されます。クライアントとして、nginx は最初に ngx_connection_t 構造体を取得し、次にソケットを作成し、ソケットの属性 (ノンブロッキングなど) を設定します。次に、読み取りイベントと書き込みイベントを追加し、connect/read/write を呼び出して接続を呼び出し、最後に接続を閉じて ngx_connection_t を解放します。 nginx では、各プロセスには接続数の上限があり、システムの fd の制限とは異なります。オペレーティング システムでは、ulimit -n を使用して、プロセスがオープンできる fd の最大数 (nofile) を取得できます。各ソケット接続は 1 つの fd を占有するため、プロセスの最大接続数も制限されます。もちろん、プログラムがサポートできる同時実行の最大数にも直接影響します。fd が使い果たされると、ソケットの作成は失敗します。 nginx は、worker_connectons を設定することによって、各プロセスでサポートされる接続の最大数を設定します。値が nofile より大きい場合、実際の最大接続数は nofile となり、nginx は警告を出します。 nginx を実装すると、各ワーカー プロセスは独立した接続プールを持ち、接続プールのサイズは worker_connections になります。ここで接続プールに保存されるものは実際には実際の接続ではなく、worker_connections のサイズの ngx_connection_t 構造体の配列にすぎません。さらに、nginx はリンク リスト free_connections を通じてすべての空き ngx_connection_t を保存し、接続が取得されるたびに、空き接続リストから取得し、使用後は空き接続リストに戻されます。 ここで、worker_connectionsパラメータの意味を誤解し、この値がnginxが確立できる接続の最大値であると考える人が多いでしょう。実際、この値は各ワーカー プロセスによって確立できる接続の最大数を表します。したがって、nginx によって確立できる接続の最大数は、worker_connections * worker_processes になります。もちろん、ここで話しているのは、ローカル リソースへの HTTP リクエストの最大接続数であり、HTTP がリバース プロキシとして使用されている場合、サポートできる同時実行の最大数は、worker_connections * worker_processes です。同時実行数はworker_connectionsである必要があります。 * ワーカープロセス/2。リバース プロキシ サーバーとして、各同時接続はクライアントとの接続とバックエンド サービスとの接続を確立し、2 つの接続を占有することになるためです。 前に述べたように、クライアントが接続した後、複数のアイドル状態のプロセスが接続をめぐって競合します。特定のプロセスが受け入れられる可能性が高ければ、そのアイドル状態の接続が不公平になることは簡単にわかります。事前に何らかの制御が行われていない場合、新しい TCP 接続が受け入れられたときに、アイドル状態の接続が取得できず、接続が他のプロセスに転送されず、最終的に TCP 接続が失われます。処理されないため、中止されます。明らかに、これは不公平です。一部のプロセスには空き接続があっても、空き接続がないため、それらを処理する機会がありません。では、この問題をどうやって解決すればよいでしょうか?まず、nginx の処理は、まず accept_mutex オプションをオンにする必要があります。このとき、accept_mutex を取得したプロセスのみが accept イベントを追加します。つまり、プロセスが accept イベントを追加するかどうかを制御します。 nginx は、ngx_accept_disabled という変数を使用して、accept_mutex ロックを競合するかどうかを制御します。コードの最初の部分では、ngx_accept_disabled の値を計算します。この値は、単一の nginx プロセス内の接続の合計数の 8 分の 1 であり、結果として得られる ngx_accept_disabled の数はパターンになります。残りの接続数が未満である 値が 0 より大きくなるのは、接続総数の 8 分の 1 が存在する場合のみであり、残りの接続数が少ないほど、値は大きくなります。 2 番目のコードを見ると、ngx_accept_disabled が 0 より大きい場合、accept_mutex ロックの取得は試行されず、ngx_accept_disabled は 1 ずつ減分されます。したがって、ここで実行されるたびに、ロックが解除されるまで 1 ずつ減分されます。は0未満です。 accept_mutex ロックを取得しないことは、接続を取得する機会を放棄することと同じです。空き接続が少ないほど、ngx_accept_disable が大きくなり、より多くの機会が与えられるため、他のプロセスに機会が与えられることがわかります。ロックの取得も軽減されます。受け入れない場合は、自分の接続が制御され、他のプロセスの接続プールが使用されます。このように、nginx は複数のプロセス間の接続のバランスを制御します。 ngx_accept_disabled = ngx_cycle->connection_n / 8 - ngx_cycle->free_connection_n; if (ngx_accept_disabled > 0) { ngx_accept_disabled--; } else { if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { return; } if (ngx_accept_mutex_held) { flags |= NGX_POST_EVENTS; } else { if (timer == NGX_TIMER_INFINITE || timer > ngx_accept_mutex_delay) { timer = ngx_accept_mutex_delay; } } }それでは、まず接続について紹介しましょう。この章の目的は、nginx における接続とは何かを理解することです。この接続は、 で使用される比較的高度な使用法です。後続のモジュール開発には、接続とイベントの実装と使用法を説明する専用の章があります。

上記では、nginx の接続の概念をその側面も含めて紹介しましたが、PHP チュートリアルに興味のある友人に役立つことを願っています。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。