NodeJSはどのようにして「ノンブロッキング」にできますか?


14

私はNodeJSを学んでおり、何かを明確にしたかっただけです。これまでのいくつかの入門チュートリアルと本では、非常に早い段階でNodeの「ノンブロッキング」アーキテクチャについて説明しました。

したがって、たとえば、この例は、データベースからデータを取得する非同期的な方法を読んでいる本で提供されました。

http.createServer(function (req, res) {
  database.getInformation(function (data) {
      res.writeHead(200);
      res.end(data);
  });
});

(私が理解しているように)起こることは、Nodeがデータベースへの呼び出しを行い、次に呼び出しスタックの次のものを処理し続けることです。データベースリクエストが完了すると、匿名コールバック関数のデータ変数が設定され、その関数がコールスタックに追加されます(その後、ノードがそれに到達したときに実行されます)。

私の質問は、データベース要求を正確に処理しているのは何ですか?確かにNodeはブロックしなければなりませんか?データベース要求を処理しているのは何ですか?または、Nodeが外部リソースへの非同期HTTP GETリクエストを待機している場合、Nodeがコールスタックの処理を継続して「非ブロッキング」になることを可能にするリクエストを処理しているのは何ですか?

回答:


17

Node.jsが「非ブロッキング」と記述されている場合、それは具体的にはそのIOが非ブロッキングであることを意味します。Nodeはlibuvを使用して、プラットフォームに依存しない方法でIOを処理します。WindowsではIO完了ポートを使用し、UNIXではepoll / kqueue / select / etcを使用します。そのため、非ブロッキングIOリクエスト(バックグラウンドスレッドモニタリングがある場合がありますが、JavaScriptに公開されることはありません)を作成し、その結果、メインのJavaScriptコールバックを呼び出すイベントループ内でそれをキューに入れます(読み取り:のみ)JavaScriptスレッド。

データベースの場合、ライブラリの作成方法によって異なります。HTTPを使用して通信する場合(一部のNoSQLデータベースと同様)、標準ノードhttpライブラリを使用して純粋なJavaScriptで簡単に記述できます。別の方法で実行する場合、それはライブラリ次第です。C / C ++で記述し、その抽象化がJavaScriptに決して公開されない限り、バックグラウンドスレッドを使用できます。

データベースリクエストの「処理」に関する質問については、ライブラリに単純なメッセージ(SQLステートメントやその他のクエリ、接続要求など)を送信することが理想的です。その時点でJavaScript動き続けます。ライブラリがメッセージを送り返す準備ができると、コールバックを実行するノードのイベントキューにメッセージを送り返し、コードのスニペットを実行できるようにします。


nethttpが利用できない場合、パッケージがあります。
フローリアンマーゲイン

役立つかもしれない詳細。NodeはV8 JSエンジンを活用します。V8の最も優れた機能の1つは、C / C ++プロセスをJS呼び出しに簡単にバインドできることです。JavaScript関数はブロックされますが、関数が行うことは、ブロックされない内部の何かを呼び出すことだけです。そのプロセスが完了すると、別のJS関数が応答します。JS関数がお互いをブロックしているということは、マルチスレッドを管理する必要があると想定している同じファイルの場所に同時に書き込みをスケジュールするようなことをしようとすることが2つないことを意味します。リクエストをキューイングするためにどのリクエストが最初に来たかは常に明確です。
エリックReppen 16年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.