Node.jsはイベント駆動型のI/Oであり、コールバックに基づいて動作し、メインスレッドでブロックしないシングルスレッドサーバーです。
スレッドベーススレッドにタスクを割り当てるモデル。アイドルスレッドがない場合は、新しいタスクをブロックします。
イベント駆動型とスレッドベースのサーバーシステムの違い(advantages/disadvantages)はどうなっているのでしょうか。
違いは次のように説明されます(簡略化されています)。
「スレッド駆動型」ランタイムでは、リクエストが到着すると、新しいスレッドが作成され、すべての処理はそのスレッドで行われます。
「イベント駆動型」ランタイムでは、リクエストが着信すると、イベントがディスパッチされ、ハンドラーがそれを取得します。いつ? Node.jsには、「イベントループ」があります。これは、基本的に、実行する必要があるすべてのコードをループし、それらを1つずつ実行します。そのため、ハンドラーは、イベントループが呼び出したイベントを処理します。ここで重要なことは、すべてのハンドラーが同じスレッドで呼び出されることです。イベントループには使用するスレッドプールがなく、1つのスレッドしかありません。
「イベント駆動型」モデルでは、ハンドラーが終了するのに非常に長い時間がかかる場合(つまり、計算量の多いfor
ループを内部に持つことにより)、イベントループ現在のハンドラが完了する前に次のハンドラを呼び出しません。 Javascriptの非同期性のため、通常は問題になりません。
一方、「スレッド駆動型」モデルでは、ハンドラーの完了に時間がかかる場合、他のスレッドは独立して同時に実行できるため、他のスレッドをそれほど傷つけることはありません。
残念ながら、新しいスレッドを作成するとオーバーヘッドが追加され、数千の同時接続を処理する必要がある場合は負担になる可能性があります。 Node.jsが高速と見なされるのはこのためです。処理する接続の数に関係なく、スレッドは1つしかありません 1 。何かを動かし続けるために、どのハンドラもブロックしないように注意する必要があります。幸いなことに、ほとんどの場合、ブロッキングJavaScriptコードを書くのはそれほど簡単ではありません。
また、ほとんどのランタイムで非同期コードの記述が可能であることに注意することも重要です。ただし、Javascriptの性質により、Node.jsで最も広く使用されるようになりました。そのおかげで、Nodeで使用するほぼすべてのライブラリは非同期になります。
イベントループの説明については、 この記事(および写真) を参照してください。
1 もちろんNode.jsプロセスには複数のスレッドがあり、それらのいくつかはI/Oに関連しています。ただし、アプリのロジックは1つのスレッドで処理されます。