1. 解決策
各ワーカー プロセスが作成されると、 ngx_worker_process_init() メソッドが呼び出され、現在のワーカー プロセスが初期化されます。このプロセスのステップ、つまり、各ワーカー プロセスは epoll_create() メソッドを呼び出して、それ自体に一意の epoll ハンドルを作成します。監視する必要があるポートごとに、それに対応するファイル記述子があり、ワーカー プロセスは epoll_ctl() メソッドを通じて現在のプロセスの epoll ハンドルにファイル記述子を追加し、accept イベントをリッスンするだけです。クライアントの接続確立イベントを使用してイベントを処理します。ここから、ワーカー プロセスが監視する必要があるポートに対応するファイル記述子をプロセスの epoll ハンドルに追加しない場合、対応するイベントをトリガーできないこともわかります。この原則に基づいて、nginx は共有ロックを使用して、現在のプロセスに監視する必要があるポートを現在のプロセスの epoll ハンドルに追加する権限があるかどうかを制御します。つまり、ロックを取得したプロセスのみがリッスンします。ターゲットポートに接続します。このようにして、イベントが発生するたびに 1 つのワーカー プロセスのみがトリガーされることが保証されます。次の図は、ワーカー プロセスの作業サイクルの概略図です。
図のプロセスに関して説明する必要があるのは、各ワーカー プロセスがサイクルに入ります。共有ロックの取得を試みます。取得できない場合は、監視対象ポートのファイル記述子が現在のプロセスの epoll ハンドルから削除されます (存在しない場合でも削除されます)。これの主な目的は損失を防ぐことです。クライアント接続イベントは、少量の雷を伴う群れの問題を引き起こす可能性がありますが、深刻なものではありません。想像してみてください。理論によれば、現在のプロセスがロックを解放するときにリスニング ポートのファイル記述子が epoll ハンドルから削除され、次のワーカー プロセスがロックを取得する前に、この期間中の各ポートに対応するファイル記述子は次のようになります。リッスンする epoll ハンドルがない場合、イベントは失われます。一方、図のようにロックの取得に失敗した場合にのみ監視対象のファイル記述子が削除される場合、ロックの取得に失敗するということは、現在そのファイル記述子を監視しているプロセスが存在するはずなので安全です。現時点でそれらを削除するには。しかし、これによって引き起こされる問題の 1 つは、上の図によると、現在のプロセスがループの実行を完了すると、ロックを解放してから他のイベントを処理することです。このプロセス中に監視対象のファイル記述子は解放されないことに注意してください。 。このとき、別のプロセスがロックを取得してファイルディスクリプタを監視している場合、この時点でファイルディスクリプタを監視しているプロセスは2つあるため、クライアント上でコネクション確立イベントが発生すると2つのワーカーが起動されることになります。この問題は、次の 2 つの主な理由により許容されます:
この種の激しい群れ現象は、少数のワーカー プロセスのみをトリガーするため、毎回すべてのワーカー プロセスを起動するよりも優れています。
- ##この種のパニック問題が発生する主な理由は、現在のプロセスはロックを解放しますが、監視対象のファイル記述子は解放しませんが、ワーカー プロセスは主にファイル記述子を解放した後にロックを解放することです。ロック。読み取りおよび書き込みイベントを処理し、クライアント接続のフラグ ビットをチェックします。このプロセスは非常に短いです。処理が完了すると、ロックの取得が試行されます。このとき、監視されているファイル記述子はこれに比べて、ロックを取得するワーカー プロセスは、クライアントの接続確立イベントの処理をより長く待機するため、雷を伴う群れの問題が発生する可能性は依然として比較的小さいということです。
2. ソースコードの説明
void ngx_process_events_and_timers(ngx_cycle_t *cycle) { ngx_uint_t flags; ngx_msec_t timer, delta; if (ngx_trylock_accept_mutex(cycle) == ngx_error) { return; } // 这里开始处理事件,对于kqueue模型,其指向的是ngx_kqueue_process_events()方法, // 而对于epoll模型,其指向的是ngx_epoll_process_events()方法 // 这个方法的主要作用是,在对应的事件模型中获取事件列表,然后将事件添加到ngx_posted_accept_events // 队列或者ngx_posted_events队列中 (void) ngx_process_events(cycle, timer, flags); // 这里开始处理accept事件,将其交由ngx_event_accept.c的ngx_event_accept()方法处理; ngx_event_process_posted(cycle, &ngx_posted_accept_events); // 开始释放锁 if (ngx_accept_mutex_held) { ngx_shmtx_unlock(&ngx_accept_mutex); } // 如果不需要在事件队列中进行处理,则直接处理该事件 // 对于事件的处理,如果是accept事件,则将其交由ngx_event_accept.c的ngx_event_accept()方法处理; // 如果是读事件,则将其交由ngx_http_request.c的ngx_http_wait_request_handler()方法处理; // 对于处理完成的事件,最后会交由ngx_http_request.c的ngx_http_keepalive_handler()方法处理。 // 这里开始处理除accept事件外的其他事件 ngx_event_process_posted(cycle, &ngx_posted_events); }上記のコードでは、ほとんどのチェック作業が省略されており、スケルトンコード。まず、ワーカー プロセスは ngx_trylock_accept_mutex() メソッドを呼び出してロックを取得し、ロックを取得すると、各ポートに対応するファイル記述子をリッスンします。次に、ngx_process_events() メソッドが呼び出され、epoll ハンドルで監視されているイベントが処理されます。その後、共有ロックが解放され、最後に接続されたクライアントの読み取りおよび書き込みイベントが処理されます。 ngx_trylock_accept_mutex() メソッドが共有ロックを取得する方法を見てみましょう:
ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle) { // 尝试使用cas算法获取共享锁 if (ngx_shmtx_trylock(&ngx_accept_mutex)) { // ngx_accept_mutex_held为1表示当前进程已经获取到了锁 if (ngx_accept_mutex_held && ngx_accept_events == 0) { return ngx_ok; } // 这里主要是将当前连接的文件描述符注册到对应事件的队列中,比如kqueue模型的change_list数组 // nginx在启用各个worker进程的时候,默认情况下,worker进程是会继承master进程所监听的socket句柄的, // 这就导致一个问题,就是当某个端口有客户端事件时,就会把监听该端口的进程都给唤醒, // 但是只有一个worker进程能够成功处理该事件,而其他的进程被唤醒之后发现事件已经过期, // 因而会继续进入等待状态,这种现象称为"惊群"现象。 // nginx解决惊群现象的方式一方面是通过这里的共享锁的方式,即只有获取到锁的worker进程才能处理 // 客户端事件,但实际上,worker进程是通过在获取锁的过程中,为当前worker进程重新添加各个端口的监听事件, // 而其他worker进程则不会监听。也就是说同一时间只有一个worker进程会监听各个端口, // 这样就避免了"惊群"问题。 // 这里的ngx_enable_accept_events()方法就是为当前进程重新添加各个端口的监听事件的。 if (ngx_enable_accept_events(cycle) == ngx_error) { ngx_shmtx_unlock(&ngx_accept_mutex); return ngx_error; } // 标志当前已经成功获取到了锁 ngx_accept_events = 0; ngx_accept_mutex_held = 1; return ngx_ok; } // 前面获取锁失败了,因而这里需要重置ngx_accept_mutex_held的状态,并且将当前连接的事件给清除掉 if (ngx_accept_mutex_held) { // 如果当前进程的ngx_accept_mutex_held为1,则将其重置为0,并且将当前进程在各个端口上的监听 // 事件给删除掉 if (ngx_disable_accept_events(cycle, 0) == ngx_error) { return ngx_error; } ngx_accept_mutex_held = 0; } return ngx_ok; }上記のコードでは、基本的に 3 つの主要な処理を実行します:
- ngx_shmtx_trylock を渡す() メソッドは、cas メソッドを使用して共有ロックを取得しようとします。
- ロックを取得した後、ngx_enable_accept_events() メソッドが呼び出され、ターゲット ポートに対応するファイル記述子をリッスンします。 ;
- ロックが取得できない場合は、ngx_disable_accept_events() メソッドを呼び出して、監視対象のファイル記述子を解放します。
以上がnginxパニックグループの問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

Nginxunitは、複数のプログラミング言語をサポートし、動的構成、ゼロダウンタイム更新、組み込みのロードバランシングなどの機能を提供するオープンソースアプリケーションサーバーです。 1。動的構成:再起動せずに構成を変更できます。 2。多言語サポート:Python、Go、Java、PHPなどと互換性があります。 4。ビルトインロードバランシング:リクエストは、複数のアプリケーションインスタンスに配布できます。

nginxunitは、多言語プロジェクトや動的な構成要件に適した、apachetomcat、gunicorn、node.jsビルトインHTTPサーバーよりも優れています。 1)複数のプログラミング言語をサポートします。2)動的な構成リロード、3)高いスケーラビリティと信頼性を必要とするプロジェクトに適した組み込みの負荷分散機能を提供します。

Nginxunitは、モジュラーアーキテクチャと動的な再構成機能により、アプリケーションのパフォーマンスと管理性を向上させます。 1)モジュラー設計には、マスタープロセス、ルーター、アプリケーションプロセスが含まれ、効率的な管理と拡張をサポートします。 2)動的再構成により、CI/CD環境に適した、実行時に構成をシームレスに更新できます。 3)多言語サポートは、言語ランタイムの動的なロードを通じて実装され、開発の柔軟性が向上します。 4)イベント駆動型モデルと非同期I/Oによって高性能が達成され、高い並行性の下でも効率的なままです。 5)申請プロセスを分離し、アプリケーション間の相互の影響を減らすことにより、セキュリティが改善されます。

nginxunitを使用して、アプリケーションを複数の言語で展開および管理できます。 1)nginxunitをインストールします。 2)PythonやPHPなどのさまざまなタイプのアプリケーションを実行するように構成します。 3)アプリケーション管理に動的構成関数を使用します。これらの手順を通じて、アプリケーションを効率的に展開および管理し、プロジェクトの効率を向上させることができます。

NGINXは、高い並行接続の処理に適していますが、Apacheは複雑な構成とモジュール拡張が必要なシナリオにより適しています。 1.Nginxは、高性能と低リソース消費で知られており、高い並行性に適しています。 2. Apacheは、その安定性とリッチモジュール拡張機能で知られています。これは、複雑な構成ニーズに適しています。

Nginxunitは、動的な構成と高性能アーキテクチャにより、アプリケーションの柔軟性とパフォーマンスを向上させます。 1.動的構成により、サーバーを再起動せずにアプリケーション構成を調整できます。 2.高性能は、イベント駆動型および非ブロッキングアーキテクチャおよびマルチプロセスモデルに反映され、同時接続を効率的に処理し、マルチコアCPUを利用できます。

NginxとApacheはどちらも強力なWebサーバーであり、それぞれがパフォーマンス、スケーラビリティ、効率の点で独自の利点と短所を備えています。 1)nginxは、静的なコンテンツを処理し、逆プロキシを逆にするときにうまく機能します。 2)Apacheは、動的コンテンツを処理するときにパフォーマンスが向上し、リッチモジュールサポートが必要なプロジェクトに適しています。サーバーの選択は、プロジェクトの要件とシナリオに基づいて決定する必要があります。

Nginxは、高い並行リクエストの処理に適していますが、Apacheは複雑な構成と機能的拡張が必要なシナリオに適しています。 1.Nginxは、イベント駆動型の非ブロッキングアーキテクチャを採用しており、高電流環境に適しています。 2。Apacheはプロセスまたはスレッドモデルを採用して、複雑な構成のニーズに適したリッチモジュールエコシステムを提供します。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

MinGW - Minimalist GNU for Windows
このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

ホットトピック









