Node.jsとは何ですか?JavaScriptランタイムの説明

スケーラビリティ、遅延、およびスループットは、Webサーバーの主要業績評価指標です。スケールアップおよびスケールアウト中にレイテンシーを低く、スループットを高く保つことは容易ではありません。Node.jsは、リクエストを処理するための「ノンブロッキング」アプローチを採用することで、低レイテンシと高スループットを実現するJavaScriptランタイム環境です。つまり、Node.jsは、I / O要求が返されるのを待つために時間やリソースを浪費しません。

Webサーバーを作成する従来のアプローチでは、着信要求または接続ごとに、サーバー新しい実行スレッドを生成するか、要求を処理して応答を送信するための新しいプロセスフォークします。概念的には、これは完全に理にかなっていますが、実際には、かなりのオーバーヘッドが発生します。

産卵しながらスレッド招き少ないメモリとフォークよりもCPUのオーバーヘッドのプロセスは、それはまだ非効率的であることができます。多数のスレッドが存在すると、負荷の高いシステムがスレッドのスケジューリングとコンテキストスイッチングに貴重なサイクルを費やす可能性があり、これにより遅延が追加され、スケーラビリティとスループットに制限が課せられます。

Node.jsは別のアプローチを取ります。システムに登録されたシングルスレッドのイベントループを実行して接続を処理し、新しい接続ごとにJavaScriptコールバック関数を起動します。コールバック関数は、非ブロッキングI / O呼び出しで要求を処理でき、必要に応じてプールからスレッドを生成して、ブロッキングまたはCPUを集中的に使用する操作を実行し、CPUコア間で負荷分散を行うことができます。コールバック関数を使用したスケーリングに対するノードのアプローチは、Apache HTTPサーバー、さまざまなJavaアプリケーションサーバー、IISとASP.NET、Ruby on Railsなど、スレッドを使用してスケーリングするほとんどの競合アーキテクチャよりも、より多くの接続を処理するために必要なメモリが少なくて済みます。

Node.jsは、サーバーだけでなくデスクトップアプリケーションにも非常に役立つことがわかりました。また、ノードアプリケーションは純粋なJavaScriptに限定されないことに注意してください。TypeScriptやCoffeeScriptなど、JavaScriptに変換される任意の言語を使用できます。Node.jsには、BabelなどのES6からES5へのトランスパイラーを必要とせずにECMAScript 2015(ES6)構文をサポートするGoogle Chrome V8JavaScriptエンジンが組み込まれています。

Nodeのユーティリティの多くは、npmコマンドからアクセスできる大きなパッケージライブラリから取得されます。NodeパッケージマネージャーであるNPMは、独自のWebサイトを持っていますが、標準のNode.jsインストールの一部です。

いくつかのJavaScriptの歴史

1995年、当時Netscapeの請負業者だったBrendan Eichは、Webブラウザで実行するJavaScript言語を10日で作成しました。JavaScriptは当初、ブラウザドキュメントオブジェクトモデル(DOM)のアニメーションやその他の操作を可能にすることを目的としていました。その後まもなく、Netscape EnterpriseServer用のJavaScriptのバージョンが導入されました。

当時SunのJava言語が広く宣伝されていたため、JavaScriptという名前がマーケティング目的で選ばれました。実際、JavaScript言語は、実際には主にScheme言語とSelf言語に基づいており、表面的なJavaのようなセマンティクスを備えていました。

当初、多くのプログラマーは、JavaScriptのインタープリターがコンパイルされた言語よりも桁違いに遅いため、JavaScriptを「実際の作業」には役に立たないと却下しました。JavaScriptを高速化することを目的としたいくつかの研究努力が実を結び始めたため、状況は変わりました。最も顕著なのは、ジャストインタイムのコンパイル、インライン化、動的コード最適化を行うオープンソースのGoogle Chrome V8 JavaScriptエンジンは、実際には一部の負荷でC ++コードを上回り、ほとんどのユースケースでPythonを上回っています。

JavaScriptベースのNode.jsプラットフォームは、Apache HTTPサーバーのよりスケーラブルな代替手段として、LinuxおよびMacOS用にRyanDahlによって2009年に導入されました。Isaac Schlueterによって作成されたNPMは、2010年にリリースされました。Node.jsのネイティブWindowsバージョンは2011年にデビューしました。

Joyentは、Node.jsの開発作業を長年にわたって所有、管理、およびサポートしてきました。2015年に、Node.jsプロジェクトはNode.js Foundationに引き渡され、Foundationの技術運営委員会によって統治されるようになりました。Node.jsは、Linux Foundation CollaborativeProjectとしても採用されました。2019年、Node.jsFoundationとJSFoundationが合併してOpenJSFoundationを形成しました。

基本的なNode.jsアーキテクチャ

高レベルでは、Node.jsはGoogle V8 JavaScriptエンジン、シングルスレッドの非ブロッキングイベントループ、および低レベルのI / OAPIを組み合わせています。以下に示す簡略化されたサンプルコード=>は、コールバックにES6矢印関数(太い矢印演算子を使用して宣言された匿名のLambda関数)を使用した基本的なHTTPサーバーパターンを示しています。

コードの最初はHTTPモジュールをロードし、サーバーhostname変数をlocalhost(127.0.0.1)に設定し、port変数を3000に設定します。次に、サーバーとコールバック関数(この場合は常に同じものを返す太い矢印関数)を作成します。リクエストへの応答:statusCode200(成功)、コンテンツタイプのプレーンテキスト、およびのテキスト応答”Hello World\n”。最後に、localhost(ソケットを介して)ポート3000でリッスンするようサーバーに指示し、サーバーがリッスンを開始したときにコンソールにログメッセージを出力するコールバックを定義します。nodeコマンドを使用してターミナルまたはコンソールでこのコードを実行し、同じマシン上の任意のWebブラウザーを使用してlocalhost:3000を参照すると、ブラウザーに「HelloWorld」が表示されます。サーバーを停止するには、ターミナルウィンドウでControl-Cを押します。

この例で行われるすべての呼び出しは非同期であり、非ブロッキングであることに注意してください。コールバック関数は、イベントに応答して呼び出されます。createServerコールバックは、クライアントの要求イベントを処理し、応答を返します。listenコールバックは、ハンドルlisteningイベントを。

Node.jsライブラリ

下の図の左側にあるように、Node.jsのライブラリにはさまざまな機能があります。前のサンプルコードで使用したHTTPモジュールには、図の右側に示されているように、クライアントクラスとサーバークラスの両方が含まれています。TLSまたはSSLを使用するHTTPSサーバー機能は、別のモジュールにあります。

シングルスレッドイベントループに固有の問題の1つは、イベントループスレッドが単一のCPUコアのみを使用するため、垂直スケーリングがないことです。一方、最近のCPUチップは8つ以上のコアを公開することが多く、最近のサーバーラックには複数のCPUチップが搭載されていることがよくあります。シングルスレッドアプリケーションは、堅牢なサーバーラックの24以上のコアを十分に活用できません。

追加のプログラミングが必要ですが、修正できます。まず、Node.jsは、システムpopen(3)コールが機能する方法と同様に、child_process.spawn() 関連するメソッドを使用して、子プロセスを生成し、親と子の間のパイプを維持できます。

クラスターモジュールは、スケーラブルサーバーを作成するための子プロセスモジュールよりもさらに興味深いものです。このcluster.fork()メソッドはchild_process.spawn()、カバーの下を使用して、親のサーバーポートを共有するワーカープロセスを生成します。クラスターマスターは、デフォルトで、ワーカープロセスの負荷に敏感なラウンドロビンアルゴリズムを使用して、着信接続をワーカー間で分散します。

Node.jsはルーティングロジックを提供しないことに注意してください。クラスタ内の接続間で状態を維持する場合は、セッションとログインオブジェクトをワーカーRAM以外の場所に保持する必要があります。

Node.jsパッケージエコシステム

NPMレジストリは、無料で再利用可能なNode.jsコードの120万を超えるパッケージをホストしているため、世界最大のソフトウェアレジストリになっています。ほとんどのNPMパッケージ(基本的には、package.jsonファイルで記述されたプログラムを含むフォルダーまたはNPMレジストリアイテム)には、複数のモジュールrequireステートメントでロードするプログラム)が含まれていることに注意してください。 2つの用語を混同するのは簡単ですが、この文脈では、それらには特定の意味があり、交換するべきではありません。

NPMは、特定のプロジェクトのローカル依存関係であるパッケージ、およびグローバルにインストールされたJavaScriptツールを管理できます。NPMをローカルプロジェクトの依存関係マネージャーとして使用すると、1つのコマンドでpackage.jsonファイルを介してプロジェクトのすべての依存関係をインストールできます。グローバルインストールに使用する場合、NPMは多くの場合システム(sudo)特権を必要とします。

パブリックNPMレジストリにアクセスするためにNPMコマンドラインを使用する必要はありません。FacebookのYarnなどの他のパッケージマネージャーは、代替のクライアント側エクスペリエンスを提供します。NPM Webサイトを使用して、パッケージを検索および参照することもできます。

なぜNPMパッケージを使いたいのですか?多くの場合、NPMコマンドラインを介したパッケージのインストールは、環境で実行されているモジュールの最新の安定バージョンを取得するのに最も速くて便利であり、通常、ソースリポジトリのクローンを作成してリポジトリからインストールを構築するよりも作業が少なくて済みます。最新バージョンが必要ない場合は、NPMにバージョン番号を指定できます。これは、あるパッケージが別のパッケージに依存していて、依存関係の新しいバージョンで破損する可能性がある場合に特に便利です。

たとえば、最小限で柔軟なNode.js WebアプリケーションフレームワークであるExpressフレームワークは、単一ページ、複数ページ、およびハイブリッドWebアプリケーションを構築するための堅牢な機能セットを提供します。簡単に複製できるExpresscodeリポジトリは//github.com/expressjs/expressにあり、Expressのドキュメントは//expressjs.com/にありますが、Expressの使用を開始する簡単な方法は、すでに初期化されたローカル作業開発にインストールすることです。npmコマンドを含むディレクトリ。例:

$ npm install express —保存

この—saveオプションは、NPM 5.0以降ではデフォルトで実際にオンになっており、インストール後にパッケージマネージャーにパッケージマネージャーにパッケージ.jsonファイルの依存関係リストにExpressモジュールを追加するように指示します。

Expressの使用を開始するもう1つの簡単な方法は、実行可能ジェネレーターをexpress(1) グローバルにインストールし、それを使用して、新しい作業フォルダーにローカルでアプリケーションを作成することです。

$ npm install -g express-generator @ 4

$ express / tmp / foo && cd / tmp / foo

これが完了すると、ジェネレーターによって作成されたpackage.jsonファイルの内容に基づいて、NPMを使用して必要なすべての依存関係をインストールし、サーバーを起動できます。

$ npmインストール

$ npm start

NPMの100万以上のパッケージからハイライトを選ぶのは難しいですが、いくつかのカテゴリが際立っています。 Expressは、Node.jsフレームワークの最も古くて最も有名な例です。 NPMリポジトリのもう1つの大きなカテゴリは、モジュールバンドラーであるbrowserifyを含むJavaScript開発ユーティリティです。 Bower、ブラウザパッケージマネージャー。 JavaScriptタスクランナーのgrunt。とgulp、ストリーミングビルドシステム。最後に、エンタープライズNode.js開発者にとって重要なカテゴリはデータベースクライアントであり、redis、mongoose、firebase、pg、PostgreSQLクライアントなどの人気のあるモジュールを含む8,000以上があります。

要約すると、Node.jsは、サーバーとアプリケーション用のクロスプラットフォームのJavaScriptランタイム環境です。これは、シングルスレッドのノンブロッキングイベントループ、Google Chrome V8 JavaScriptエンジン、および低レベルI / OAPIに基づいて構築されています。クラスターモジュールを含むさまざまな手法により、Node.jsアプリは単一のCPUコアを超えて拡張できます。Node.jsは、そのコア機能を超えて、NPMリポジトリに登録およびバージョン管理され、NPMコマンドラインまたはYarnなどの代替手段を使用してインストールできる100万を超えるパッケージのエコシステムに影響を与えました。