84669 人が学習中
152542 人が学習中
20005 人が学習中
5487 人が学習中
7821 人が学習中
359900 人が学習中
3350 人が学習中
180660 人が学習中
48569 人が学習中
18603 人が学習中
40936 人が学習中
1549 人が学習中
1183 人が学習中
32909 人が学習中
Nginx はリクエストの処理を複数のフェーズ (フェーズ) に分割します。これらの段階で IO ブロックは発生しますか?ブロッキングがある場合、Nginxは他のリクエストを実行しますが、他のリクエストを実行するときに優先順位の区別はありますか(すでに後の段階に進んでいるリクエストが最初に実行されますか?)?また、Nginx には各段階で処理するためのスレッド プールがあるのでしょうか、それとも最初から最後まで独自のスレッドを持つのでしょうか?
cat /proc/3776/status|grep Threads Nginx ワーカー プロセスにはスレッドが 1 つだけあり、そのうちの 3776 が Nginx ワーカー プロセスの PID であることがわかります。さらに、Nginx は 1.7.11 から AIO スレッド プールのサポートを追加し、AIO マルチスレッドを使用して大きなファイルの読み取りと送信を行うことで、ワーカー プロセスがブロックされるのを防ぐことができます (小さなファイルには sendfile を使用し、大きなファイルには AIO スレッド プールを使用します) ) スレッド プールのサポートを有効にするには、構成時に --with-threads オプションを明示的に追加する必要があります。 https://www.nginx.com/blog/thread-pools-boost-performance-9x/http://nginx.org/en/docs/ngx_core_module.html#thread_pool
cat /proc/3776/status|grep Threads
転送: listen_fd に新しい accept() リクエストがあると、オペレーティング システムはすべての子プロセスを起動します。これは、これらのプロセスはすべて同じ listen_fd の epoll_wait() を処理し、オペレーティング システムには、誰が受け入れる責任があるかを判断する方法がないためです。したがって、単にすべてのプロセスを起動しますが、最終的には 1 つのプロセスだけが正常に受け入れられ、他のプロセスはすべて「怖がって目覚める」ことになります。そのため、これは Thundering Herd と呼ばれます。
http://nginx.org/en/docs/ngx_core_module.html#accept_mutex具体的な対策には、グローバルミューテックスロック (accept_mutex をオン) の使用が含まれます。 epoll_wait()でワーカープロセスにロックを申請し、アプリケーションが取得できれば処理を続行、取得できない場合は待機し、負荷分散アルゴリズムを設定する(ある作業プロセスのタスク量が7/8に達したとき)各プロセスのワークロードのバランスをとるために、設定された合計ボリュームを再試行する必要はありません。
NGINX 1.9.1 はソケット シャーディングをサポートします: http://nglua.com/docs/sharding.htmlNGINX1.9.1 は、次の SO_REUSEPORT オプションをサポートしますソケット、このオプションは、DragonFly BSD および Linux (3.9 以降のカーネル) を含む、多くのオペレーティング システムの新しいバージョンで使用できます。このオプションにより、カーネルは、これらのソケットへの受信接続を同じ IP アドレスとポートの組み合わせでリッスンできるようになります。効果的な断片化。SO_REUSEPORT オプションがオンになっていない場合、接続が到着すると、デフォルトで待機ソケットがプロセスに通知します。この時点で accept_mutex off コマンドがすべてのワーカー プロセスを起動する場合、ワーカー プロセスはそれを取得するために競合します。これはいわゆるサンダーリング現象です。ロックなし (accept_mutex オフ) で epoll を使用すると、SO_REUSEPORT オプションが有効になった後、リスニングポートで読み取り操作が行われると、サンダーリング現象が発生します。カーネルは、接続を取得するための有効なソケット (プロセス) を決定します。これにより、ワーカー プロセスの待機時間が短縮され、処理の準備が整う前に新しい接続が提供されることになります。彼ら
nginx は、デフォルトでは 1 つのマスター プロセスと複数のワーカー プロセスで動作し、複数のワーカー プロセスがクライアントからのリクエストを均等に処理するために使用されます。ただし、他のワーカー プロセスからのリクエストを処理することはできません。各ワーカー プロセスには 1 つのメイン スレッドしかありません。epoll のサポートにより、非同期の非ブロッキング メソッドを使用してリクエストを処理し、複数のイベントの監視をサポートします (ソケット ポーリング)。イベントの準備ができていない場合は、イベントを epoll に入れます。イベントの準備ができたら、読み取りと書き込みを行います。このイベント処理方法には、スレッドを作成する必要がなく、各リクエストが占有されます。また、メモリが非常に少なく、コンテキストの切り替えが行われず、イベント処理は非常に軽量です。同時実行の数が増えても、不必要なリソースの浪費にはつながりません (コンテキストの切り替えが増えると、より多くのメモリが消費されるだけです)。 httpd の一般的な動作方法は、各リクエストが作業スレッドを占有することです。同時実行数が数千に達すると、同時に数千のスレッドがリクエストを処理することになります。これは、オペレーティング システムのメモリ使用量にとって大きな課題となります。これによって引き起こされる CPU オーバーヘッドは非常に大きく、当然のことながら、Tengine チームは 24G メモリを備えたマシンで Nginx の処理数をテストしました。同時リクエスト数は 200 万件以上に達しています (平均 1G メモリで 80,000 件以上のリクエストを処理できます)。Nginx は特定のプロセスを特定のコアにバインドする (CPU アフィニティ バインド) ことをサポートしているため、問題は発生しません。プロセスの切り替えを回避するには、CPU のコア数に応じて複数のワーカー プロセスを設定することをお勧めします。ただし、ワーカー プロセスが多すぎると、プロセスが CPU リソースを競合するだけになり、不要なコンテキストが発生することに注意してください。したがって、ワーカー プロセスのプロセスは多ければ多いほど良いです。
cat /proc/3776/status|grep Threads
Nginx ワーカー プロセスにはスレッドが 1 つだけあり、そのうちの 3776 が Nginx ワーカー プロセスの PID であることがわかります。さらに、Nginx は 1.7.11 から AIO スレッド プールのサポートを追加し、AIO マルチスレッドを使用して大きなファイルの読み取りと送信を行うことで、ワーカー プロセスがブロックされるのを防ぐことができます (小さなファイルには sendfile を使用し、大きなファイルには AIO スレッド プールを使用します) ) スレッド プールのサポートを有効にするには、構成時に --with-threads オプションを明示的に追加する必要があります。https://www.nginx.com/blog/thread-pools-boost-performance-9x/
http://nginx.org/en/docs/ngx_core_module.html#thread_pool
転送:
待機ソケットは起動時に初期化されます。Nginx は、これらのソケットを介してリクエストを受け入れ、読み取り、応答を出力します。この作業は、オペレーティング システムのカーネル メカニズムによって行われます。そのため、パニック現象が発生する可能性があります。つまり、listen_fd に新しい accept() リクエストがあると、オペレーティング システムがすべての子プロセスを起動します。listen_fd に新しい accept() リクエストがあると、オペレーティング システムはすべての子プロセスを起動します。これは、これらのプロセスはすべて同じ listen_fd の epoll_wait() を処理し、オペレーティング システムには、誰が受け入れる責任があるかを判断する方法がないためです。したがって、単にすべてのプロセスを起動しますが、最終的には 1 つのプロセスだけが正常に受け入れられ、他のプロセスはすべて「怖がって目覚める」ことになります。そのため、これは Thundering Herd と呼ばれます。
http://nginx.org/en/docs/ngx_core_module.html#accept_mutex
雷の群れを解決するための Nginx の新しい方法: カーネルによって提供される Socket ReusePort 関数を使用します具体的な対策には、グローバルミューテックスロック (accept_mutex をオン) の使用が含まれます。 epoll_wait()でワーカープロセスにロックを申請し、アプリケーションが取得できれば処理を続行、取得できない場合は待機し、負荷分散アルゴリズムを設定する(ある作業プロセスのタスク量が7/8に達したとき)各プロセスのワークロードのバランスをとるために、設定された合計ボリュームを再試行する必要はありません。
NGINX 1.9.1 はソケット シャーディングをサポートします:
http://nglua.com/docs/sharding.html
NGINX1.9.1 は、次の SO_REUSEPORT オプションをサポートしますソケット、このオプションは、DragonFly BSD および Linux (3.9 以降のカーネル) を含む、多くのオペレーティング システムの新しいバージョンで使用できます。このオプションにより、カーネルは、これらのソケットへの受信接続を同じ IP アドレスとポートの組み合わせでリッスンできるようになります。効果的な断片化。SO_REUSEPORT オプションがオンになっていない場合、接続が到着すると、デフォルトで待機ソケットがプロセスに通知します。この時点で accept_mutex off コマンドがすべてのワーカー プロセスを起動する場合、ワーカー プロセスはそれを取得するために競合します。これはいわゆるサンダーリング現象です。ロックなし (accept_mutex オフ) で epoll を使用すると、SO_REUSEPORT オプションが有効になった後、リスニングポートで読み取り操作が行われると、サンダーリング現象が発生します。カーネルは、接続を取得するための有効なソケット (プロセス) を決定します。これにより、ワーカー プロセスの待機時間が短縮され、処理の準備が整う前に新しい接続が提供されることになります。彼ら
nginx は、デフォルトでは 1 つのマスター プロセスと複数のワーカー プロセスで動作し、複数のワーカー プロセスがクライアントからのリクエストを均等に処理するために使用されます。ただし、他のワーカー プロセスからのリクエストを処理することはできません。各ワーカー プロセスには 1 つのメイン スレッドしかありません。epoll のサポートにより、非同期の非ブロッキング メソッドを使用してリクエストを処理し、複数のイベントの監視をサポートします (ソケット ポーリング)。イベントの準備ができていない場合は、イベントを epoll に入れます。イベントの準備ができたら、読み取りと書き込みを行います。このイベント処理方法には、スレッドを作成する必要がなく、各リクエストが占有されます。また、メモリが非常に少なく、コンテキストの切り替えが行われず、イベント処理は非常に軽量です。同時実行の数が増えても、不必要なリソースの浪費にはつながりません (コンテキストの切り替えが増えると、より多くのメモリが消費されるだけです)。 httpd の一般的な動作方法は、各リクエストが作業スレッドを占有することです。同時実行数が数千に達すると、同時に数千のスレッドがリクエストを処理することになります。これは、オペレーティング システムのメモリ使用量にとって大きな課題となります。これによって引き起こされる CPU オーバーヘッドは非常に大きく、当然のことながら、Tengine チームは 24G メモリを備えたマシンで Nginx の処理数をテストしました。同時リクエスト数は 200 万件以上に達しています (平均 1G メモリで 80,000 件以上のリクエストを処理できます)。Nginx は特定のプロセスを特定のコアにバインドする (CPU アフィニティ バインド) ことをサポートしているため、問題は発生しません。プロセスの切り替えを回避するには、CPU のコア数に応じて複数のワーカー プロセスを設定することをお勧めします。ただし、ワーカー プロセスが多すぎると、プロセスが CPU リソースを競合するだけになり、不要なコンテキストが発生することに注意してください。したがって、ワーカー プロセスのプロセスは多ければ多いほど良いです。