web-dev-qa-db-ja.com

正しいNode.jsアーキテクチャはどれですか?

Node.jsのアーキテクチャについて少し混乱しています。

Is this real one ?

enter image description here

最初のものは正しいですか? 2番目の図では、各呼び出しが最初にV8を通過し、次にNode.jsバインディングを通過しますが、最初の段階ではその逆です。理解を助けてください。前もって感謝します。

29
Sagar

最初に、最初のグラフは少し時代遅れですが、両方のグラフが正しいです。 Node.jsの非同期部分は、以前はlibev、libeio、およびlibuvで構成されていました。しかし、libuvが過去数年間で進歩したため、「 [in] libuv libevのnode-v0.9.0バージョンが削除されました 」と、libuvがNode.jsの全体を処理しました。非同期I/Oプロセス(したがって、もちろんイベントループを含む)。したがって、Node.jsアーキテクチャの最新バージョンは、「libeio」と「libev」を「libuv」に置き換えます(2番目の画像のように)。

2つのグラフの構造が異なるのは、異なる視点で整理されているためです。グラフ1は、Node.jsテクノロジーのさまざまな部分の高レベルから低レベルへの分類を表しています(したがって、ワークフローを意味するものではありません)。一方、グラフ2はNode.js操作の実際のワークフローです。

これを類推するために:グラフを使って車のさまざまな部分を表現しようとするとしましょう。これはさまざまな方法で行うことができます。分類/機能(シナリオA)ごとに異なる部分を整理することができます。

  • 電源システム:エンジン、オイル、冷却、排気など.
  • トランスミッションシステム:ギアボックス、シャフト、クラッチアセンブリ、ディファレンシャルなど.
  • サスペンションシステム:コントロールアーム、ショックアブソーバー、ステアリングコンポーネントなど.
  • ......

または、ワークフローごとにピースを整理することもできます(シナリオB):

  • オイル->エンジン->トランスミッション->差動->サスペンション->など.

(車についてはあまり詳しく知りません。部品の名前と実際のワークフローは間違っている可能性があります。理解を助けるためにのみリストされています。)

ピースを整理する方法が異なるため、表示される順序も異なります。シナリオAはグラフ1に似ており、シナリオBはグラフ2に似ています。


Node.jsの動作方法をどれだけ理解しているかわからないため、Node.jsアーキテクチャに適合するさまざまな要素の概要を簡単に説明してから、相互作用の方法を説明します。

  • V8-Chrome/ChromiumブラウザーにあるGoogleのオープンソースJavaScriptエンジン。 V8は、一般的なWebブラウザーのようにJavaScriptコードをオンザフライで解釈する代わりに、JSコードをマシンコードに変換して、非常に高速に処理します。 V8はC++で書かれています。 V8の動作の詳細については、 here を参照してください。

  • libuv-libuvはもともと非同期TCPおよびUDPソケット、(有名な)イベントループ、非同期DNSを含む非同期I/Oを提供するために開発されました解像度、ファイルシステムの読み取り/書き込みなど。libuvはCで記述されています。libuvの詳細については、 video を参照してください。

  • その他の低レベルコンポーネント- c-areshttp parserOpenSSL など、 zlib など、ほとんどがC/C++で書かれています。

  • アプリケーション-ここにコード、モジュール、Node.js ' builts in modules があり、JavaScriptで記述されています(またはTypeScript、CoffeeScriptなどを介してJSにコンパイルされています)

  • Binding-バインディングは基本的に、ある言語で記述されたライブラリのラッパーであり、ライブラリを別の言語で記述されたコードに公開して、異なる言語で記述されたコードが通信できるようにします。

最初のグラフは理にかなっているはずです。一番上は、JavaScriptで記述されたアプリケーション(モジュールおよびNode.jsの組み込みモジュール)です。下部には、C/C++で記述されたNode.js内部コンポーネントがあります。それらが通信できるようにブリッジするには、バインディングが必要です。そのため、Node.jsバインディングは、高レベルのアプリケーションと低レベルのNodeコンポーネントの間に位置します。このグラフは、必ずしもワークフローを表すものではありません。それは、互いに関係/機能に応じて異なるNode.jsピースを分類するだけです。

2番目のグラフは、Node.jsアプリケーションの実際のワークフローを表しています。アプリケーションで記述されたコードは、V8によってコンパイルされます。コードは、バインディングを介して低レベルのNode.jsコンポーネントと通信します。コードで記述されたすべてのイベントはNode.jsに登録されます。トリガーされたイベントは、トリガーされた順序に従ってイベントキューに入れられます。イベントキューにイベントが残っている限り、イベントループはそれらを取得し、コールバック関数を呼び出し、処理のためにワーカースレッドに送信し続けます。コールバック関数が実行されると、そのコールバックは再びイベントキューに送信され、イベントループによって再び取得されるのを待ちます。

混乱の一部は、2番目のグラフで使用されている専門用語の選択に起因する可能性があります。よく見ると、「NODE.JS BINDINGS」の下に「(NODE API)」と表示されていますが、これは残念ながら2つの異なるものです。 Node.js API は組み込みライブラリのインターフェースです。 bindings は、ソフトウェアプログラミングの観点から、異なる言語で記述されたコード間のブリッジです。 。

これがお役に立てば幸いです。


Node.jsの内部構造のより正確な表現は次のとおりです: Node.js Architecture (この画像は少し前にインターネット上のソースからダウンロードしましたが、どこから来たのか忘れていました。画像があなたのものである場合はコメントしてください。


編集:最近、わかりやすい類推で Node.jsのアーキテクチャ を説明するより包括的な記事を書きました。私はそれが役立つことを望みます!

64
Aren Li