Node.js を学び、使い始めて 2 ヶ月が経ちました。Express と mongoose を組み合わせて Web アプリケーションと RESTful Web API のセットを作成しました。 Node.js 公式 Web サイト: Node.js はイベント駆動型のノンブロッキング I/O モデルを使用しており、軽量かつ効率的です。 では、ノンブロッキング I/O モデルとは何を意味するのでしょうか。
ノンブロッキング IO モデル
まず、IO 操作には間違いなく時間がかかります。サーバーが大量のリクエストを受信すると、リクエストごとにプロセスまたはスレッドを作成すると、メモリのオーバーヘッドが追加され、より多くの時間リソースが浪費される可能性があります。
Node.js はイベント駆動型であるため、イベント ループを使用して IO 操作によって引き起こされるボトルネックの問題を解決します。 Node.js では、通常、IO 操作にはコールバック関数があり、IO 操作が完了して戻ると、このコールバック関数が呼び出され、メインスレッドは次のコードの実行を続けます。この問題を説明するために、単純に例を使用してみましょう:
request('http://www.google.com', function(error, response, body) { console.log(body); }); console.log('Done!');
このコードの意味は、「http://www.google.com」にリクエストを送信し、リクエストが返されると、コールバック関数が呼び出されて応答情報を出力します。 Node.jsの動作仕組み上、このコードを実行するとすぐにコンソールに「Done!」が出力され、一定時間後にレスポンス情報が出力されます。
イベントループ イベントループ
次に、イベントループの仕組みについて説明します。まず、桟の呼び出しについて説明します。たとえば、次のようなコードがあります。
function A(arg, func){ var a = arg; func(); console.log('A'); } function B(){ console.log('B'); } A(0, B);
Javascript ランタイムにはメッセージ キューがあり、イベントがトリガーされると、そのイベントに対応するコールバック関数がある場合、メッセージはメッセージ キューに追加されます。
イベント ループの正確な内容を振り返ると、コードの実行が開始された後、関数が呼び出し側バケットに継続的にプッシュされ、リクエストが呼び出し側バケットにプッシュされ、この関数が実行されます。 request (この http リクエストは Node.js の基礎となるモジュールによって実装されます) 同時に、リクエスト完了のイベントがコールバック関数に関連付けられ、console.log が作成されます。呼び出しスタックにプッシュされて実行が開始されます。リクエストが完了すると、完了イベントがトリガーされ、メッセージがメッセージ キューに追加されます。メッセージ キューは、呼び出し側スタッカーがアイドル状態であるかどうかを最初に確認します。呼び出し側スタッカーがアイドル状態でない場合は、呼び出し側スタッカーがアイドル状態になるまで待機します。アイドル状態のあと、メッセージ キューの先頭がポップアップし、メッセージに関連付けられたコールバック関数が実行されます。
概要
上記は、ノンブロッキング モデルとイベント ループの概念的な概要です。このイベント ループ メカニズムは Node.js に固有のものではなく、Node.js のコードは単一のスレッドで実行されます。大量の同時リクエストに直面した場合、どのような利点がありますか?
上の図は Node.js のアーキテクチャ図を示しています。Node.js の下部にスレッド プールの維持を担当するモジュールがあります。IO リクエストが発行されると、Node.js の下部のモジュールが実行されます。リクエストを処理する新しいスレッドを作成し、完了後に結果を上位層に返します。次に、複数のリクエストがある場合、Node.js の基礎となるモジュールは、ほとんどのタスクを完了するためにできるだけ少ないスレッドを使用し、アイドル状態のスレッドがある場合は、他のことを行うために引き続き使用されます。リクエストごとに新しいプロセスまたはスレッドを開くという点では、間違いなくはるかに「スマート」で効率的です。
この記事は Node.js の学習についてまとめたものです。問題や不足がある場合は、お気軽に批判して修正してください。